diff --git a/.env.example b/.env.example index 2a7503d5cd..afd0b235db 100644 --- a/.env.example +++ b/.env.example @@ -57,10 +57,10 @@ APP_LOG_LEVEL=notice # Database credentials. Make sure the database exists. I recommend a dedicated user for Firefly III # For other database types, please see the FAQ: https://docs.firefly-iii.org/support/faq # If you use Docker or similar, you can set these variables from a file by appending them with _FILE -# Use "mysql" for MySQL and MariaDB. Use "sqlite" for SQLite. -DB_CONNECTION=pgsql +# Use "pgsql" for PostgreSQL and MariaDB. Use "sqlite" for SQLite. +DB_CONNECTION=mysql DB_HOST=fireflyiiidb -DB_PORT=5432 +DB_PORT=3306 DB_DATABASE=firefly DB_USERNAME=firefly DB_PASSWORD=secret_firefly_password @@ -167,6 +167,23 @@ FIXER_API_KEY= # If you use Docker or similar, you can set this variable from a file by appending it with _FILE LOGIN_PROVIDER=eloquent +# +# It's also possible to change the way users are authenticated. You could use Authelia for example. +# Authentication via the REMOTE_USER header is supported. Change the value below to "remote_user_guard". +# +# If you do this please read the documentation for instructions and warnings: +# https://docs.firefly-iii.org/advanced-installation/authentication +# +# This function is available in Firefly III v5.3.0 and higher. +AUTHENTICATION_GUARD=web + +# +# Likewise, it's impossible to log out users who's authentication is handled by an external system. +# Enter a custom URL here that will force a logout (your authentication provider can tell you). +# Setting this variable only works when AUTHENTICATION_GUARD != web +# +CUSTOM_LOGOUT_URI= + # LDAP connection configuration # OpenLDAP, FreeIPA or ActiveDirectory # # If you use Docker or similar, you can set this variable from a file by appending it with _FILE @@ -289,7 +306,7 @@ DEMO_PASSWORD= USE_ENCRYPTION=false IS_SANDSTORM=false IS_HEROKU=false -BUNQ_USE_SANDBOX=false +FIREFLY_III_LAYOUT=v1 # # If you have trouble configuring your Firefly III installation, DON'T BOTHER setting this variable. diff --git a/.gitignore b/.gitignore index 0bcb66f5d4..5bf61812fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,6 @@ /node_modules /frontend/node_modules +/frontend/fonts /public/hot /public/storage /storage/*.key diff --git a/app/Api/V1/Controllers/ImportController.php b/app/Api/V1/Controllers/ImportController.php deleted file mode 100644 index 52065ac4db..0000000000 --- a/app/Api/V1/Controllers/ImportController.php +++ /dev/null @@ -1,181 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Api\V1\Controllers; - -use FireflyIII\Helpers\Collector\GroupCollectorInterface; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Http\Api\TransactionFilter; -use FireflyIII\Transformers\ImportJobTransformer; -use FireflyIII\Transformers\TransactionGroupTransformer; -use FireflyIII\User; -use Illuminate\Http\JsonResponse; -use Illuminate\Http\Request; -use Illuminate\Pagination\LengthAwarePaginator; -use Illuminate\Support\Collection; -use League\Fractal\Pagination\IlluminatePaginatorAdapter; -use League\Fractal\Resource\Collection as FractalCollection; -use League\Fractal\Resource\Item; - -/** - * Class ImportController - * - * @deprecated - * @codeCoverageIgnore - */ -class ImportController extends Controller -{ - use TransactionFilter; - /** @var ImportJobRepositoryInterface Import job repository. */ - private $repository; - - /** - * ImportController constructor. - * - * @codeCoverageIgnore - */ - public function __construct() - { - parent::__construct(); - $this->middleware( - function ($request, $next) { - /** @var User $user */ - $user = auth()->user(); - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($user); - - return $next($request); - } - ); - } - - /** - * @return JsonResponse - * @codeCoverageIgnore - */ - public function listAll(): JsonResponse - { - // create some objects: - $manager = $this->getManager(); - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; - - // get list of accounts. Count it and split it. - $collection = $this->repository->get(); - $count = $collection->count(); - $importJobs = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); - - // make paginator: - $paginator = new LengthAwarePaginator($importJobs, $count, $pageSize, $this->parameters->get('page')); - $paginator->setPath(route('api.v1.import.list') . $this->buildParams()); - - /** @var ImportJobTransformer $transformer */ - $transformer = app(ImportJobTransformer::class); - $transformer->setParameters($this->parameters); - - $resource = new FractalCollection($importJobs, $transformer, 'import_jobs'); - $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); - } - - /** - * @param ImportJob $importJob - * - * @return JsonResponse - * @codeCoverageIgnore - */ - public function show(ImportJob $importJob): JsonResponse - { - $manager = $this->getManager(); - /** @var ImportJobTransformer $transformer */ - $transformer = app(ImportJobTransformer::class); - $transformer->setParameters($this->parameters); - - $resource = new Item($importJob, $transformer, 'import_jobs'); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); - } - - /** - * Show all transactions - * - * @param Request $request - * @param ImportJob $importJob - * - * @return JsonResponse - * @codeCoverageIgnore - */ - public function transactions(Request $request, ImportJob $importJob): JsonResponse - { - $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; - $type = $request->get('type') ?? 'default'; - $this->parameters->set('type', $type); - - $types = $this->mapTransactionTypes($this->parameters->get('type')); - $manager = $this->getManager(); - - $tag = $importJob->tag; - $transactions = new Collection(); - $paginator = new LengthAwarePaginator($transactions, 0, $pageSize); - $paginator->setPath(route('api.v1.import.transactions', [$importJob->key]) . $this->buildParams()); - - if (null !== $tag) { - /** @var User $admin */ - $admin = auth()->user(); - - // use new group collector: - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - $collector - ->setUser($admin) - // filter on tag. - ->setTag($tag) - // all info needed for the API: - ->withAPIInformation() - // set page size: - ->setLimit($pageSize) - // set page to retrieve - ->setPage($this->parameters->get('page')) - // set types of transactions to return. - ->setTypes($types); - - if (null !== $this->parameters->get('start') && null !== $this->parameters->get('end')) { - $collector->setRange($this->parameters->get('start'), $this->parameters->get('end')); - } - $paginator = $collector->getPaginatedGroups(); - $paginator->setPath(route('api.v1.transactions.index') . $this->buildParams()); - $transactions = $paginator->getCollection(); - } - - /** @var TransactionGroupTransformer $transformer */ - $transformer = app(TransactionGroupTransformer::class); - $transformer->setParameters($this->parameters); - - $resource = new FractalCollection($transactions, $transformer, 'transactions'); - $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); - - return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); - } - -} diff --git a/app/Api/V1/Controllers/ObjectGroupController.php b/app/Api/V1/Controllers/ObjectGroupController.php new file mode 100644 index 0000000000..a078c61e93 --- /dev/null +++ b/app/Api/V1/Controllers/ObjectGroupController.php @@ -0,0 +1,196 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Controllers; + +use FireflyIII\Api\V1\Requests\ObjectGroupUpdateRequest; +use FireflyIII\Models\Account; +use FireflyIII\Models\ObjectGroup; +use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface; +use FireflyIII\Transformers\ObjectGroupTransformer; +use FireflyIII\Transformers\PiggyBankTransformer; +use FireflyIII\User; +use Illuminate\Http\JsonResponse; +use Illuminate\Http\Request; +use Illuminate\Pagination\LengthAwarePaginator; +use League\Fractal\Pagination\IlluminatePaginatorAdapter; +use League\Fractal\Resource\Collection as FractalCollection; +use League\Fractal\Resource\Item; + +/** + * Class GroupController. + * + */ +class ObjectGroupController extends Controller +{ + private ObjectGroupRepositoryInterface $repository; + + /** + * ObjectGroupController constructor. + * + * @codeCoverageIgnore + */ + public function __construct() + { + parent::__construct(); + $this->middleware( + function ($request, $next) { + /** @var User $user */ + $user = auth()->user(); + $this->repository = app(ObjectGroupRepositoryInterface::class); + $this->repository->setUser($user); + + return $next($request); + } + ); + } + + /** + * Remove the specified resource from storage. + * + * @param ObjectGroup $objectGroup + * + * @codeCoverageIgnore + * @return JsonResponse + */ + public function delete(ObjectGroup $objectGroup): JsonResponse + { + $this->repository->destroy($objectGroup); + + return response()->json([], 204); + } + + /** + * Display a listing of the resource. + * + * @param Request $request + * + * @codeCoverageIgnore + * @return JsonResponse + */ + public function index(Request $request): JsonResponse + { + $manager = $this->getManager(); + + // types to get, page size: + $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + + // get list of accounts. Count it and split it. + $collection = $this->repository->get(); + $count = $collection->count(); + $objectGroups = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); + + // make paginator: + $paginator = new LengthAwarePaginator($objectGroups, $count, $pageSize, $this->parameters->get('page')); + $paginator->setPath(route('api.v1.object-groups.index') . $this->buildParams()); + + /** @var ObjectGroupTransformer $transformer */ + $transformer = app(ObjectGroupTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new FractalCollection($objectGroups, $transformer, 'object_groups'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + } + + + /** + * List all piggies under the object group. + * + * @param ObjectGroup $objectGroup + * + * @return JsonResponse + * @codeCoverageIgnore + * + */ + public function piggyBanks(ObjectGroup $objectGroup): JsonResponse + { + // create some objects: + $manager = $this->getManager(); + + // types to get, page size: + $pageSize = (int) app('preferences')->getForUser(auth()->user(), 'listPageSize', 50)->data; + + // get list of piggy banks. Count it and split it. + $collection = $this->repository->getPiggyBanks($objectGroup); + $count = $collection->count(); + $piggyBanks = $collection->slice(($this->parameters->get('page') - 1) * $pageSize, $pageSize); + + // make paginator: + $paginator = new LengthAwarePaginator($piggyBanks, $count, $pageSize, $this->parameters->get('page')); + $paginator->setPath(route('api.v1.object-groups.piggy_banks', [$objectGroup->id]) . $this->buildParams()); + + /** @var PiggyBankTransformer $transformer */ + $transformer = app(PiggyBankTransformer::class); + $transformer->setParameters($this->parameters); + + $resource = new FractalCollection($piggyBanks, $transformer, 'piggy_banks'); + $resource->setPaginator(new IlluminatePaginatorAdapter($paginator)); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + + } + + /** + * Show single instance. + * + * @param ObjectGroup $objectGroup + * + * @return JsonResponse + */ + public function show(ObjectGroup $objectGroup): JsonResponse + { + $manager = $this->getManager(); + + /** @var ObjectGroupTransformer $transformer */ + $transformer = app(ObjectGroupTransformer::class); + $transformer->setParameters($this->parameters); + $resource = new Item($objectGroup, $transformer, 'object_groups'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + } + + /** + * Update object. + * + * @param ObjectGroupUpdateRequest $request + * @param Account $account + * + * @return JsonResponse + */ + public function update(ObjectGroupUpdateRequest $request, ObjectGroup $objectGroup): JsonResponse + { + $data = $request->getUpdateData(); + $this->repository->update($objectGroup, $data); + $this->repository->sort(); + $manager = $this->getManager(); + + /** @var ObjectGroupTransformer $transformer */ + $transformer = app(ObjectGroupTransformer::class); + $transformer->setParameters($this->parameters); + $resource = new Item($objectGroup, $transformer, 'object_groups'); + + return response()->json($manager->createData($resource)->toArray())->header('Content-Type', 'application/vnd.api+json'); + } +} diff --git a/app/Api/V1/Controllers/PiggyBankController.php b/app/Api/V1/Controllers/PiggyBankController.php index ec61455628..185a37636f 100644 --- a/app/Api/V1/Controllers/PiggyBankController.php +++ b/app/Api/V1/Controllers/PiggyBankController.php @@ -24,6 +24,7 @@ declare(strict_types=1); namespace FireflyIII\Api\V1\Controllers; use FireflyIII\Api\V1\Requests\PiggyBankRequest; +use FireflyIII\Api\V1\Requests\PiggyBankStoreRequest; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Models\PiggyBank; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; @@ -204,12 +205,12 @@ class PiggyBankController extends Controller /** * Store new object. * - * @param PiggyBankRequest $request + * @param PiggyBankStoreRequest $request * * @throws FireflyException * @return JsonResponse */ - public function store(PiggyBankRequest $request): JsonResponse + public function store(PiggyBankStoreRequest $request): JsonResponse { $piggyBank = $this->repository->store($request->getAll()); $manager = $this->getManager(); diff --git a/app/Import/Specifics/RabobankDescription.php b/app/Api/V1/Requests/ObjectGroupUpdateRequest.php similarity index 54% rename from app/Import/Specifics/RabobankDescription.php rename to app/Api/V1/Requests/ObjectGroupUpdateRequest.php index 1823a6bda8..57cabc7fe8 100644 --- a/app/Import/Specifics/RabobankDescription.php +++ b/app/Api/V1/Requests/ObjectGroupUpdateRequest.php @@ -1,6 +1,7 @@ . */ + declare(strict_types=1); -namespace FireflyIII\Import\Specifics; +namespace FireflyIII\Api\V1\Requests; /** - * Class RabobankDescription. + * Class AccountObjectGroupUpdateRequestUpdateRequest * * @codeCoverageIgnore - * @deprecated */ -class RabobankDescription implements SpecificInterface +class ObjectGroupUpdateRequest extends Request { + /** - * Description of this specific. + * Authorize logged in users. * - * @return string - * @codeCoverageIgnore + * @return bool */ - public static function getDescription(): string + public function authorize(): bool { - return 'import.specific_rabo_descr'; + // Only allow authenticated users + return auth()->check(); } /** - * Name of this specific. - * - * @return string - * @codeCoverageIgnore + * @return array */ - public static function getName(): string + public function getUpdateData(): array { - return 'import.specific_rabo_name'; + return [ + 'title' => $this->string('title'), + 'order' => $this->integer('order'), + ]; } /** - * Run the specific. - * - * @param array $row + * The rules that the incoming request must be matched against. * * @return array - * */ - public function run(array $row): array + public function rules(): array { - $row = array_values($row); + $objectGroup = $this->route()->parameter('objectGroup'); - return $row; + return [ + 'title' => sprintf('min:1|uniqueObjectGroup:%d', $objectGroup->id), + 'order' => 'numeric', + ]; } } diff --git a/app/Api/V1/Requests/PiggyBankStoreRequest.php b/app/Api/V1/Requests/PiggyBankStoreRequest.php new file mode 100644 index 0000000000..8d32203aa9 --- /dev/null +++ b/app/Api/V1/Requests/PiggyBankStoreRequest.php @@ -0,0 +1,86 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Api\V1\Requests; + +use FireflyIII\Rules\ZeroOrMore; + +/** + * + * Class PiggyBankStoreRequest + * + * @codeCoverageIgnore + */ +class PiggyBankStoreRequest extends Request +{ + /** + * Authorize logged in users. + * + * @return bool + */ + public function authorize(): bool + { + // Only allow authenticated users + return auth()->check(); + } + + /** + * Get all data from the request. + * + * @return array + */ + public function getAll(): array + { + return [ + 'name' => $this->string('name'), + 'account_id' => $this->integer('account_id'), + 'targetamount' => $this->string('target_amount'), + 'current_amount' => $this->string('current_amount'), + 'startdate' => $this->date('start_date'), + 'targetdate' => $this->date('target_date'), + 'notes' => $this->nlString('notes'), + 'object_group_id' => $this->integer('object_group_id'), + 'object_group' => $this->string('object_group_name'), + ]; + } + + /** + * The rules that the incoming request must be matched against. + * + * @return array + */ + public function rules(): array + { + return [ + 'name' => 'required|between:1,255|uniquePiggyBankForUser', + 'current_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount'], + 'account_id' => 'required|numeric|belongsToUser:accounts,id', + 'object_group_id' => 'numeric|belongsToUser:object_groups,id', + 'target_amount' => ['numeric', new ZeroOrMore, 'lte:target_amount', 'required'], + 'start_date' => 'date|nullable', + 'target_date' => 'date|nullable|after:start_date', + 'notes' => 'max:65000', + ]; + } + +} diff --git a/app/Console/Commands/Correction/FixRecurringTransactions.php b/app/Console/Commands/Correction/FixRecurringTransactions.php index 318fee0304..f392676942 100644 --- a/app/Console/Commands/Correction/FixRecurringTransactions.php +++ b/app/Console/Commands/Correction/FixRecurringTransactions.php @@ -55,9 +55,9 @@ class FixRecurringTransactions extends Command /** * Execute the console command. * - * @return mixed + * @return int */ - public function handle() + public function handle(): int { $start = microtime(true); $this->stupidLaravel(); diff --git a/app/Console/Commands/CreateDatabase.php b/app/Console/Commands/CreateDatabase.php index f3b55c858b..ee72d3fa17 100644 --- a/app/Console/Commands/CreateDatabase.php +++ b/app/Console/Commands/CreateDatabase.php @@ -50,9 +50,9 @@ class CreateDatabase extends Command /** * Execute the console command. * - * @return mixed + * @return int */ - public function handle() + public function handle(): int { if ('mysql' !== env('DB_CONNECTION')) { $this->info(sprintf('CreateDB does not apply to "%s", skipped.', env('DB_CONNECTION'))); diff --git a/app/Console/Commands/DecryptDatabase.php b/app/Console/Commands/DecryptDatabase.php index e1f48cc388..a568e6bd39 100644 --- a/app/Console/Commands/DecryptDatabase.php +++ b/app/Console/Commands/DecryptDatabase.php @@ -159,7 +159,7 @@ class DecryptDatabase extends Command if ('The MAC is invalid.' === $e->getMessage()) { throw new FireflyException($e->getMessage()); // @codeCoverageIgnore } - Log::debug(sprintf('Could not decrypt. %s', $e->getMessage())); + //Log::debug(sprintf('Could not decrypt. %s', $e->getMessage())); } return $value; diff --git a/app/Console/Commands/Import/CreateCSVImport.php b/app/Console/Commands/Import/CreateCSVImport.php deleted file mode 100644 index 3da93f17d8..0000000000 --- a/app/Console/Commands/Import/CreateCSVImport.php +++ /dev/null @@ -1,76 +0,0 @@ -. - */ - -/** @noinspection MultipleReturnStatementsInspection */ - -declare(strict_types=1); - -namespace FireflyIII\Console\Commands\Import; - -use Exception; -use FireflyIII\Console\Commands\VerifiesAccessToken; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Import\Routine\RoutineInterface; -use FireflyIII\Import\Storage\ImportArrayStorage; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Repositories\User\UserRepositoryInterface; -use FireflyIII\User; -use Illuminate\Console\Command; -use Log; - -/** - * Class CreateCSVImport. - * - * @deprecated - * @codeCoverageIgnore - */ -class CreateCSVImport extends Command -{ - use VerifiesAccessToken; - /** - * The console command description. - * - * @var string - */ - protected $description = 'Use this command to create a new CSV file import.'; - /** - * The name and signature of the console command. - * - * @var string - */ - protected $signature - = 'firefly-iii:csv-import - {file? : The CSV file to import.} - {configuration? : The configuration file to use for the import.} - {--user=1 : The user ID that the import should import for.} - {--token= : The user\'s access token.}'; - /** - * Run the command. - */ - public function handle(): int - { - $this->error('This command is disabled.'); - return 1; - } - - -} diff --git a/app/Console/Commands/Tools/ApplyRules.php b/app/Console/Commands/Tools/ApplyRules.php index 8a9fd90b5b..612b2e0f41 100644 --- a/app/Console/Commands/Tools/ApplyRules.php +++ b/app/Console/Commands/Tools/ApplyRules.php @@ -60,7 +60,7 @@ class ApplyRules extends Command */ protected $signature = 'firefly-iii:apply-rules - {--user=1 : The user ID that the import should import for.} + {--user=1 : The user ID.} {--token= : The user\'s access token.} {--accounts= : A comma-separated list of asset accounts or liabilities to apply your rules to.} {--rule_groups= : A comma-separated list of rule groups to apply. Take the ID\'s of these rule groups from the Firefly III interface.} diff --git a/app/Exceptions/GracefulNotFoundHandler.php b/app/Exceptions/GracefulNotFoundHandler.php index 9169e2c67e..b5221eca31 100644 --- a/app/Exceptions/GracefulNotFoundHandler.php +++ b/app/Exceptions/GracefulNotFoundHandler.php @@ -38,6 +38,7 @@ use Illuminate\Http\Request; use Illuminate\Routing\Redirector; use Log; use Symfony\Component\HttpFoundation\Response; +use Throwable; /** * Class GracefulNotFoundHandler @@ -53,7 +54,7 @@ class GracefulNotFoundHandler extends ExceptionHandler * @throws Exception * @return mixed */ - public function render($request, Exception $exception) + public function render($request, Throwable $exception) { $route = $request->route(); if (null === $route) { @@ -136,12 +137,12 @@ class GracefulNotFoundHandler extends ExceptionHandler /** * @param Request $request - * @param Exception $exception + * @param Throwable $exception * * @throws Exception * @return Redirector|Response */ - private function handleAccount(Request $request, Exception $exception) + private function handleAccount(Request $request, Throwable $exception) { Log::debug('404 page is probably a deleted account. Redirect to overview of account types.'); /** @var User $user */ @@ -164,12 +165,12 @@ class GracefulNotFoundHandler extends ExceptionHandler /** * @param Request $request - * @param Exception $exception + * @param Throwable $exception * * @throws Exception * @return RedirectResponse|Redirector|Response */ - private function handleAttachment(Request $request, Exception $exception) + private function handleAttachment(Request $request, Throwable $exception) { Log::debug('404 page is probably a deleted attachment. Redirect to parent object.'); /** @var User $user */ @@ -208,13 +209,13 @@ class GracefulNotFoundHandler extends ExceptionHandler } /** - * @param Request $request + * @param Throwable $request * @param Exception $exception * * @throws Exception * @return RedirectResponse|\Illuminate\Http\Response|Redirector|Response */ - private function handleGroup(Request $request, Exception $exception) + private function handleGroup(Request $request, Throwable $exception) { Log::debug('404 page is probably a deleted group. Redirect to overview of group types.'); /** @var User $user */ diff --git a/app/Exceptions/Handler.php b/app/Exceptions/Handler.php index 6ffeca74e2..c5e4254c2f 100644 --- a/app/Exceptions/Handler.php +++ b/app/Exceptions/Handler.php @@ -33,9 +33,9 @@ use Illuminate\Auth\AuthenticationException; use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler; use Illuminate\Validation\ValidationException as LaravelValidationException; use League\OAuth2\Server\Exception\OAuthServerException; -use Request; use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - +use Illuminate\Http\Request; +use Throwable; /** * Class Handler * @@ -51,7 +51,7 @@ class Handler extends ExceptionHandler * * @return mixed */ - public function render($request, Exception $exception) + public function render($request, Throwable $exception) { if ($exception instanceof LaravelValidationException && $request->expectsJson()) { // ignore it: controller will handle it. @@ -119,7 +119,7 @@ class Handler extends ExceptionHandler * * @return void */ - public function report(Exception $exception) + public function report(Throwable $exception) { $doMailError = config('firefly.send_error_message'); // if the user wants us to mail: @@ -143,13 +143,13 @@ class Handler extends ExceptionHandler 'line' => $exception->getLine(), 'code' => $exception->getCode(), 'version' => config('firefly.version'), - 'url' => Request::fullUrl(), - 'userAgent' => Request::userAgent(), - 'json' => Request::acceptsJson(), + 'url' => request()->fullUrl(), + 'userAgent' => request()->userAgent(), + 'json' => request()->acceptsJson(), ]; // create job that will mail. - $ipAddress = Request::ip() ?? '0.0.0.0'; + $ipAddress = request()->ip() ?? '0.0.0.0'; $job = new MailError($userData, (string) config('firefly.site_owner'), $ipAddress, $data); dispatch($job); } diff --git a/app/Helpers/Collector/Extensions/CollectorProperties.php b/app/Helpers/Collector/Extensions/CollectorProperties.php index ae05ce6338..fd55907012 100644 --- a/app/Helpers/Collector/Extensions/CollectorProperties.php +++ b/app/Helpers/Collector/Extensions/CollectorProperties.php @@ -36,6 +36,8 @@ trait CollectorProperties private $hasAccountInfo; /** @var bool Will be true if query result includes bill information. */ private $hasBillInformation; + /** @var bool */ + private $hasNotesInformation; /** @var bool Will be true if query result contains budget info. */ private $hasBudgetInformation; /** @var bool Will be true if query result contains category info. */ diff --git a/app/Helpers/Collector/Extensions/MetaCollection.php b/app/Helpers/Collector/Extensions/MetaCollection.php index 0f92abbbaf..ea0bea686f 100644 --- a/app/Helpers/Collector/Extensions/MetaCollection.php +++ b/app/Helpers/Collector/Extensions/MetaCollection.php @@ -28,6 +28,7 @@ use FireflyIII\Models\Budget; use FireflyIII\Models\Category; use FireflyIII\Models\Tag; use Illuminate\Database\Eloquent\Builder as EloquentBuilder; +use Illuminate\Database\Query\JoinClause; use Illuminate\Support\Collection; /** @@ -36,6 +37,27 @@ use Illuminate\Support\Collection; trait MetaCollection { + /** + * @inheritDoc + */ + public function withNotes(): GroupCollectorInterface + { + if (false === $this->hasNotesInformation) { + // join bill table + $this->query->leftJoin( + 'notes', + static function (JoinClause $join) { + $join->on('notes.noteable_id', '=', 'transaction_journals.id'); + $join->where('notes.noteable_type', '=', 'FireflyIII\Models\TransactionJournal'); + } + ); + // add fields + $this->fields[] = 'notes.text as notes'; + $this->hasNotesInformation = true; + } + + return $this; + } /** * Limit the search to a specific bill. diff --git a/app/Helpers/Collector/GroupCollector.php b/app/Helpers/Collector/GroupCollector.php index 4540f41a32..b3bfbf4e75 100644 --- a/app/Helpers/Collector/GroupCollector.php +++ b/app/Helpers/Collector/GroupCollector.php @@ -62,6 +62,7 @@ class GroupCollector implements GroupCollectorInterface $this->hasCatInformation = false; $this->hasBudgetInformation = false; $this->hasBillInformation = false; + $this->hasNotesInformation = false; $this->hasJoinedTagTables = false; $this->hasJoinedAttTables = false; $this->integerFields = [ @@ -552,9 +553,14 @@ class GroupCollector implements GroupCollectorInterface $result['tags'] = []; $result['attachments'] = []; try { - $result['date'] = new Carbon($result['date']); - $result['created_at'] = new Carbon($result['created_at']); - $result['updated_at'] = new Carbon($result['updated_at']); + $result['date'] = new Carbon($result['date'], 'UTC'); + $result['created_at'] = new Carbon($result['created_at'], 'UTC'); + $result['updated_at'] = new Carbon($result['updated_at'], 'UTC'); + + // this is going to happen a lot: + $result['date']->setTimezone(env('TZ')); + $result['created_at']->setTimezone(env('TZ')); + $result['updated_at']->setTimezone(env('TZ')); } catch (Exception $e) { Log::error($e->getMessage()); } @@ -681,4 +687,5 @@ class GroupCollector implements GroupCollectorInterface ->orderBy('transaction_journals.description', 'DESC') ->orderBy('source.amount', 'DESC'); } + } diff --git a/app/Helpers/Collector/GroupCollectorInterface.php b/app/Helpers/Collector/GroupCollectorInterface.php index 6975ca7b44..17a4e4f0ca 100644 --- a/app/Helpers/Collector/GroupCollectorInterface.php +++ b/app/Helpers/Collector/GroupCollectorInterface.php @@ -398,6 +398,13 @@ interface GroupCollectorInterface */ public function withCategoryInformation(): GroupCollectorInterface; + /** + * Will include notes. + * + * @return GroupCollectorInterface + */ + public function withNotes(): GroupCollectorInterface; + /** * Add tag info. * diff --git a/app/Http/Controllers/Account/EditController.php b/app/Http/Controllers/Account/EditController.php index 4afb528e68..576f9fb867 100644 --- a/app/Http/Controllers/Account/EditController.php +++ b/app/Http/Controllers/Account/EditController.php @@ -49,8 +49,7 @@ class EditController extends Controller /** @var AccountRepositoryInterface The account repository */ private $repository; - /** @var AttachmentHelperInterface Helper for attachments. */ - private $attachments; + private AttachmentHelperInterface $attachments; /** * EditController constructor. @@ -67,7 +66,7 @@ class EditController extends Controller $this->repository = app(AccountRepositoryInterface::class); $this->currencyRepos = app(CurrencyRepositoryInterface::class); - $this->attachments = app(AttachmentHelperInterface::class); + $this->attachments = app(AttachmentHelperInterface::class); return $next($request); } diff --git a/app/Http/Controllers/Account/ReconcileController.php b/app/Http/Controllers/Account/ReconcileController.php index c16ce9facd..85e47b0be9 100644 --- a/app/Http/Controllers/Account/ReconcileController.php +++ b/app/Http/Controllers/Account/ReconcileController.php @@ -130,7 +130,6 @@ class ReconcileController extends Controller $startDate = clone $start; $startDate->subDay(); $startBalance = round(app('steam')->balance($account, $startDate), $currency->decimal_places); - $endBalance = round(app('steam')->balance($account, $end), $currency->decimal_places); $subTitleIcon = config(sprintf('firefly.subIconsByIdentifier.%s', $account->accountType->type)); $subTitle = (string) trans('firefly.reconcile_account', ['account' => $account->name]); diff --git a/app/Http/Controllers/Account/ShowController.php b/app/Http/Controllers/Account/ShowController.php index b2f5f973ff..68841905b2 100644 --- a/app/Http/Controllers/Account/ShowController.php +++ b/app/Http/Controllers/Account/ShowController.php @@ -46,10 +46,8 @@ class ShowController extends Controller { use UserNavigation, PeriodOverview; - /** @var CurrencyRepositoryInterface The currency repository */ - private $currencyRepos; - /** @var AccountRepositoryInterface The account repository */ - private $repository; + private CurrencyRepositoryInterface $currencyRepos; + private AccountRepositoryInterface $repository; /** * ShowController constructor. diff --git a/app/Http/Controllers/Auth/LoginController.php b/app/Http/Controllers/Auth/LoginController.php index 6db9e4f5b1..5c359e40d2 100644 --- a/app/Http/Controllers/Auth/LoginController.php +++ b/app/Http/Controllers/Auth/LoginController.php @@ -176,4 +176,35 @@ class LoginController extends Controller throw $exception; } + + /** + * Log the user out of the application. + * + * @param \Illuminate\Http\Request $request + * + * @return \Illuminate\Http\Response + */ + public function logout(Request $request) + { + $authGuard = config('firefly.authentication_guard'); + $logoutUri = config('firefly.custom_logout_uri'); + if ('remote_user_guard' === $authGuard && '' !== $logoutUri) { + return redirect($logoutUri); + } + + $this->guard()->logout(); + + $request->session()->invalidate(); + + $request->session()->regenerateToken(); + + if ($response = $this->loggedOut($request)) { + return $response; + } + + return $request->wantsJson() + ? new \Illuminate\Http\Response('', 204) + : redirect('/'); + } + } diff --git a/app/Http/Controllers/BillController.php b/app/Http/Controllers/BillController.php index 2c12d48479..ee674fa8ab 100644 --- a/app/Http/Controllers/BillController.php +++ b/app/Http/Controllers/BillController.php @@ -211,14 +211,20 @@ class BillController extends Controller /** @var Collection $bills */ $bills = $unfiltered->map( function (Bill $bill) use ($transformer, $defaultCurrency) { - $return = $transformer->transform($bill); - $currency = $bill->transactionCurrency ?? $defaultCurrency; - $return['currency_id'] = $currency->id; - $return['currency_name'] = $currency->name; - $return['currency_symbol'] = $currency->symbol; - $return['currency_code'] = $currency->code; - $return['currency_decimal_places'] = $currency->decimal_places; - $return['attachments'] = $this->billRepository->getAttachments($bill); + $return = $transformer->transform($bill); + $nextExpectedMatch = new Carbon($return['next_expected_match']); + $return['next_expected_match_diff'] = $nextExpectedMatch->isToday() + ? trans('firefly.today') + : $nextExpectedMatch->diffForHumans( + today(), Carbon::DIFF_RELATIVE_TO_NOW + ); + $currency = $bill->transactionCurrency ?? $defaultCurrency; + $return['currency_id'] = $currency->id; + $return['currency_name'] = $currency->name; + $return['currency_symbol'] = $currency->symbol; + $return['currency_code'] = $currency->code; + $return['currency_decimal_places'] = $currency->decimal_places; + $return['attachments'] = $this->billRepository->getAttachments($bill); return $return; } diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index 04807b3468..a54c40afba 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -39,13 +39,13 @@ class Controller extends BaseController use AuthorizesRequests, DispatchesJobs, ValidatesRequests, UserNavigation, RequestInformation; /** @var string Format for date and time. */ - protected $dateTimeFormat; + protected string $dateTimeFormat; /** @var string Format for "23 Feb, 2016". */ - protected $monthAndDayFormat; + protected string $monthAndDayFormat; /** @var string Format for "March 2018" */ - protected $monthFormat; + protected string $monthFormat; /** @var string Redirect user */ - protected $redirectUri = '/'; + protected string $redirectUri = '/'; /** * Controller constructor. @@ -55,7 +55,7 @@ class Controller extends BaseController public function __construct() { // is site a demo site? - $isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site',),)->data; + $isDemoSite = app('fireflyconfig')->get('is_demo_site', config('firefly.configuration.is_demo_site', false,),)->data; app('view')->share('IS_DEMO_SITE', $isDemoSite,); app('view')->share('DEMO_USERNAME', config('firefly.demo_username')); app('view')->share('DEMO_PASSWORD', config('firefly.demo_password')); diff --git a/app/Http/Controllers/DebugController.php b/app/Http/Controllers/DebugController.php index 03eb6b2d83..e77f40c4ba 100644 --- a/app/Http/Controllers/DebugController.php +++ b/app/Http/Controllers/DebugController.php @@ -138,6 +138,8 @@ class DebugController extends Controller $appLogLevel = config('logging.level'); $cacheDriver = config('cache.default'); $loginProvider = config('auth.providers.users.driver'); + $bcscale = bcscale(); + $layout = env('FIREFLY_III_LAYOUT'); // some new vars. $telemetry = true === config('firefly.send_telemetry') && true === config('firefly.feature_flags.telemetry'); @@ -195,6 +197,8 @@ class DebugController extends Controller 'drivers', 'currentDriver', 'loginProvider', + 'bcscale', + 'layout', 'userAgent', 'displayErrors', 'installationId', @@ -224,15 +228,14 @@ class DebugController extends Controller { $set = RouteFacade::getRoutes(); $ignore = ['chart.', 'javascript.', 'json.', 'report-data.', 'popup.', 'debugbar.', 'attachments.download', 'attachments.preview', - 'bills.rescan', 'budgets.income', 'currencies.def', 'error', 'flush', 'help.show', 'import.file', + 'bills.rescan', 'budgets.income', 'currencies.def', 'error', 'flush', 'help.show', 'login', 'logout', 'password.reset', 'profile.confirm-email-change', 'profile.undo-email-change', 'register', 'report.options', 'routes', 'rule-groups.down', 'rule-groups.up', 'rules.up', 'rules.down', 'rules.select', 'search.search', 'test-flash', 'transactions.link.delete', 'transactions.link.switch', - 'two-factor.lost', 'reports.options', 'debug', 'import.create-job', 'import.download', 'import.start', 'import.status.json', + 'two-factor.lost', 'reports.options', 'debug', 'preferences.delete-code', 'rules.test-triggers', 'piggy-banks.remove-money', 'piggy-banks.add-money', 'accounts.reconcile.transactions', 'accounts.reconcile.overview', - 'transactions.clone', 'two-factor.index', 'api.v1', 'installer.', 'attachments.view', 'import.create', - 'import.job.download', 'import.job.start', 'import.job.status.json', 'import.job.store', 'recurring.events', + 'transactions.clone', 'two-factor.index', 'api.v1', 'installer.', 'attachments.view', 'recurring.events', 'recurring.suggest', ]; $return = ' '; diff --git a/app/Http/Controllers/Import/CallbackController.php b/app/Http/Controllers/Import/CallbackController.php deleted file mode 100644 index 9e9c8ad65a..0000000000 --- a/app/Http/Controllers/Import/CallbackController.php +++ /dev/null @@ -1,82 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Http\Controllers\Import; - - -use FireflyIII\Http\Controllers\Controller; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Contracts\View\Factory; -use Illuminate\Http\RedirectResponse; -use Illuminate\Http\Request; -use Illuminate\Routing\Redirector; -use Illuminate\View\View; -use Log; - -/** - * Class CallbackController - * - * @deprecated - * @codeCoverageIgnore - */ -class CallbackController extends Controller -{ - - /** - * Callback specifically for YNAB logins. - * - * @param Request $request - * - * @param ImportJobRepositoryInterface $repository - * - * @return Factory|RedirectResponse|Redirector|View - */ - public function ynab(Request $request, ImportJobRepositoryInterface $repository) - { - $code = (string) $request->get('code'); - $jobKey = (string) $request->get('state'); - - if ('' === $code) { - return view('error')->with('message', 'You Need A Budget did not reply with a valid authorization code. Firefly III cannot continue.'); - } - - $importJob = $repository->findByKey($jobKey); - - if ('' === $jobKey || null === $importJob) { - return view('error')->with('message', 'You Need A Budget did not reply with the correct state identifier. Firefly III cannot continue.'); - } - Log::debug(sprintf('Got a code from YNAB: %s', $code)); - - // we have a code. Make the job ready for the next step, and then redirect the user. - $configuration = $repository->getConfiguration($importJob); - $configuration['auth_code'] = $code; - $repository->setConfiguration($importJob, $configuration); - - // set stage to make the import routine take the correct action: - $repository->setStatus($importJob, 'ready_to_run'); - $repository->setStage($importJob, 'get_access_token'); - - return redirect(route('import.job.status.index', [$importJob->key])); - } - -} diff --git a/app/Http/Controllers/Import/IndexController.php b/app/Http/Controllers/Import/IndexController.php deleted file mode 100644 index d06579bded..0000000000 --- a/app/Http/Controllers/Import/IndexController.php +++ /dev/null @@ -1,198 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Http\Controllers\Import; - -use FireflyIII\Http\Controllers\Controller; -use FireflyIII\Import\Prerequisites\PrerequisitesInterface; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Repositories\User\UserRepositoryInterface; -use FireflyIII\Support\Binder\ImportProvider; -use Illuminate\Contracts\View\Factory; -use Illuminate\Http\RedirectResponse; -use Illuminate\Http\Response as LaravelResponse; -use Illuminate\Routing\Redirector; -use Illuminate\View\View; -use Log; - -/** - * - * Class IndexController - * - * @deprecated - * @codeCoverageIgnore - */ -class IndexController extends Controller -{ - /** @var array All available providers */ - public $providers; - /** @var ImportJobRepositoryInterface The import job repository */ - public $repository; - /** @var UserRepositoryInterface The user repository */ - public $userRepository; - - /** - * IndexController constructor. - */ - public function __construct() - { - parent::__construct(); - - $this->middleware( - function ($request, $next) { - app('view')->share('mainTitleIcon', 'fa-archive'); - app('view')->share('title', (string) trans('firefly.import_index_title')); - $this->repository = app(ImportJobRepositoryInterface::class); - $this->userRepository = app(UserRepositoryInterface::class); - $this->providers = ImportProvider::getProviders(); - - return $next($request); - } - ); - } - - /** - * Creates a new import job for $importProvider. - * - * @param string $importProvider - * - * @return RedirectResponse|Redirector - * - */ - public function create(string $importProvider) - { - $hasPreReq = (bool) config(sprintf('import.has_prereq.%s', $importProvider)); - $hasConfig = (bool) config(sprintf('import.has_job_config.%s', $importProvider)); - $allowedForDemo = (bool) config(sprintf('import.allowed_for_demo.%s', $importProvider)); - $isDemoUser = $this->userRepository->hasRole(auth()->user(), 'demo'); - - Log::debug(sprintf('Will create job for provider "%s"', $importProvider)); - Log::debug(sprintf('Is demo user? %s', var_export($isDemoUser, true))); - Log::debug(sprintf('Is allowed for user? %s', var_export($allowedForDemo, true))); - Log::debug(sprintf('Has prerequisites? %s', var_export($hasPreReq, true))); - Log::debug(sprintf('Has config? %s', var_export($hasConfig, true))); - - // @codeCoverageIgnoreStart - if ($isDemoUser && !$allowedForDemo) { - Log::debug('User is demo and this provider doesnt work for demo users.'); - - return redirect(route('import.index')); - } - // @codeCoverageIgnoreEnd - - $importJob = $this->repository->create($importProvider); - - Log::debug(sprintf('Created job #%d for provider %s', $importJob->id, $importProvider)); - - // no prerequisites but job has config: - if (false === $hasPreReq && false !== $hasConfig) { - Log::debug('Provider has no prerequisites. Continue.'); - $this->repository->setStatus($importJob, 'has_prereq'); - Log::debug('Redirect to configuration.'); - - return redirect(route('import.job.configuration.index', [$importJob->key])); - } - - // job has prerequisites: - Log::debug('Job provider has prerequisites.'); - /** @var PrerequisitesInterface $providerPre */ - $providerPre = app((string) config(sprintf('import.prerequisites.%s', $importProvider))); - $providerPre->setUser($importJob->user); - - // and are not filled in: - if (!$providerPre->isComplete()) { - Log::debug('Job provider prerequisites are not yet filled in. Redirect to prerequisites-page.'); - - // redirect to global prerequisites - return redirect(route('import.prerequisites.index', [$importProvider, $importJob->key])); - } - Log::debug('Prerequisites are complete.'); - - // but are filled in: - $this->repository->setStatus($importJob, 'has_prereq'); - - // and has no config: - if (false === $hasConfig) { - // @codeCoverageIgnoreStart - Log::debug('Provider has no configuration. Job is ready to start.'); - $this->repository->setStatus($importJob, 'ready_to_run'); - Log::debug('Redirect to status-page.'); - - return redirect(route('import.job.status.index', [$importJob->key])); - // @codeCoverageIgnoreEnd - } - - // but also needs config: - Log::debug('Job has configuration. Redirect to job-config.'); - - // Otherwise just redirect to job configuration. - return redirect(route('import.job.configuration.index', [$importJob->key])); - - } - - /** - * Generate a JSON file of the job's configuration and send it to the user. - * - * @param ImportJob $job - * - * @return LaravelResponse - */ - public function download(ImportJob $job): LaravelResponse - { - Log::debug('Now in download()', ['job' => $job->key]); - $config = $this->repository->getConfiguration($job); - // This is CSV import specific: - $config['delimiter'] = $config['delimiter'] ?? ','; - $config['delimiter'] = "\t" === $config['delimiter'] ? 'tab' : $config['delimiter']; - - $result = json_encode($config, JSON_PRETTY_PRINT); - $name = sprintf('"%s"', addcslashes('import-configuration-' . date('Y-m-d') . '.json', '"\\')); - /** @var LaravelResponse $response */ - $response = response($result); - $response->header('Content-disposition', 'attachment; filename=' . $name) - ->header('Content-Type', 'application/json') - ->header('Content-Description', 'File Transfer') - ->header('Connection', 'Keep-Alive') - ->header('Expires', '0') - ->header('Cache-Control', 'must-revalidate, post-check=0, pre-check=0') - ->header('Pragma', 'public') - ->header('Content-Length', strlen($result)); - - return $response; - } - - /** - * General import index. - * - * @return Factory|View - */ - public function index() - { - $providers = $this->providers; - $subTitle = (string) trans('import.index_breadcrumb'); - $subTitleIcon = 'fa-home'; - $isDemoUser = $this->userRepository->hasRole(auth()->user(), 'demo'); - - return view('import.index', compact('subTitle', 'subTitleIcon', 'providers', 'isDemoUser')); - } -} diff --git a/app/Http/Controllers/Import/JobConfigurationController.php b/app/Http/Controllers/Import/JobConfigurationController.php deleted file mode 100644 index 50c4ba1aa5..0000000000 --- a/app/Http/Controllers/Import/JobConfigurationController.php +++ /dev/null @@ -1,169 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Http\Controllers\Import; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Http\Controllers\Controller; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Http\Controllers\CreateStuff; -use Illuminate\Contracts\View\Factory; -use Illuminate\Http\RedirectResponse; -use Illuminate\Http\Request; -use Illuminate\Http\UploadedFile; -use Illuminate\Routing\Redirector; -use Illuminate\Support\MessageBag; -use Illuminate\View\View; -use Log; - -/** - * Class JobConfigurationController - * - * @deprecated - * @codeCoverageIgnore - */ -class JobConfigurationController extends Controller -{ - use CreateStuff; - /** @var ImportJobRepositoryInterface The import job repository */ - public $repository; - - /** - * JobConfigurationController constructor. - */ - public function __construct() - { - parent::__construct(); - - $this->middleware( - function ($request, $next) { - app('view')->share('mainTitleIcon', 'fa-archive'); - app('view')->share('title', (string) trans('firefly.import_index_title')); - $this->repository = app(ImportJobRepositoryInterface::class); - - return $next($request); - } - ); - } - - /** - * Configure the job. This method is returned to until job is deemed "configured". - * - * @param ImportJob $importJob - * - * @throws FireflyException - * - * @return Factory|RedirectResponse|Redirector|View - * - */ - public function index(ImportJob $importJob) - { - Log::debug('Now in JobConfigurationController::index()'); - $allowed = ['has_prereq', 'need_job_config']; - if (null !== $importJob && !in_array($importJob->status, $allowed, true)) { - Log::error(sprintf('Job has state "%s", but we only accept %s', $importJob->status, json_encode($allowed))); - session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)])); - - return redirect(route('import.index')); - } - Log::debug(sprintf('Now in JobConfigurationController::index() with job "%s" and status "%s"', $importJob->key, $importJob->status)); - - // if provider has no config, just push it through: - $importProvider = $importJob->provider; - if (!(bool) config(sprintf('import.has_job_config.%s', $importProvider))) { - // @codeCoverageIgnoreStart - Log::debug('Job needs no config, is ready to run!'); - $this->repository->setStatus($importJob, 'ready_to_run'); - - return redirect(route('import.job.status.index', [$importJob->key])); - // @codeCoverageIgnoreEnd - } - - $configurator = $this->makeConfigurator($importJob); - if ($configurator->configurationComplete()) { - Log::debug('Config is complete, set status to ready_to_run.'); - $this->repository->setStatus($importJob, 'ready_to_run'); - - return redirect(route('import.job.status.index', [$importJob->key])); - } - - $view = $configurator->getNextView(); - $data = $configurator->getNextData(); - $subTitle = (string) trans('import.job_configuration_breadcrumb', ['key' => $importJob->key]); - $subTitleIcon = 'fa-wrench'; - - return view($view, compact('data', 'importJob', 'subTitle', 'subTitleIcon')); - } - - /** - * Store the configuration. Returns to "configure" method until job is configured. - * - * @param Request $request - * @param ImportJob $importJob - * - * @throws FireflyException - * @return RedirectResponse|Redirector - * - */ - public function post(Request $request, ImportJob $importJob) - { - // catch impossible status: - $allowed = ['has_prereq', 'need_job_config']; - if (null !== $importJob && !in_array($importJob->status, $allowed, true)) { - session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)])); - - return redirect(route('import.index')); - } - - Log::debug('Now in postConfigure()', ['job' => $importJob->key]); - $configurator = $this->makeConfigurator($importJob); - - // is the job already configured? - if ($configurator->configurationComplete()) { - $this->repository->setStatus($importJob, 'ready_to_run'); - - return redirect(route('import.job.status.index', [$importJob->key])); - } - - // uploaded files are attached to the job. - // the configurator can then handle them. - $result = new MessageBag; - - /** @var UploadedFile $upload */ - foreach ($request->allFiles() as $name => $upload) { - $result = $this->repository->storeFileUpload($importJob, $name, $upload); - } - $data = $request->all(); - $messages = $configurator->configureJob($data); - $result->merge($messages); - - if ($messages->count() > 0) { - $request->session()->flash('warning', $messages->first()); - } - - // return to configure - return redirect(route('import.job.configuration.index', [$importJob->key])); - } - - -} diff --git a/app/Http/Controllers/Import/JobStatusController.php b/app/Http/Controllers/Import/JobStatusController.php deleted file mode 100644 index f90dc9f383..0000000000 --- a/app/Http/Controllers/Import/JobStatusController.php +++ /dev/null @@ -1,240 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Http\Controllers\Import; - -use Exception; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Http\Controllers\Controller; -use FireflyIII\Import\Routine\RoutineInterface; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Http\Controllers\CreateStuff; -use Illuminate\Http\JsonResponse; -use Log; - -/** - * Class JobStatusController - * - * @deprecated - * @codeCoverageIgnore - */ -class JobStatusController extends Controller -{ - use CreateStuff; - /** @var ImportJobRepositoryInterface The import job repository */ - private $repository; - - /** - * JobStatusController constructor. - */ - public function __construct() - { - parent::__construct(); - // set time limit to zero to prevent timeouts. - set_time_limit(0); - - $this->middleware( - function ($request, $next) { - app('view')->share('mainTitleIcon', 'fa-archive'); - app('view')->share('title', (string) trans('firefly.import_index_title')); - $this->repository = app(ImportJobRepositoryInterface::class); - - return $next($request); - } - ); - } - - /** - * Index for job status. - * - * @param ImportJob $importJob - * - * @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View - */ - public function index(ImportJob $importJob) - { - $subTitleIcon = 'fa-gear'; - $subTitle = (string) trans('import.job_status_breadcrumb', ['key' => $importJob->key]); - - return view('import.status', compact('importJob', 'subTitle', 'subTitleIcon')); - } - - /** - * JSON overview of job status. - * - * @param ImportJob $importJob - * - * @return JsonResponse - */ - public function json(ImportJob $importJob): JsonResponse - { - $count = $this->repository->countTransactions($importJob); - $json = [ - 'status' => $importJob->status, - 'errors' => $importJob->errors, - 'count' => $count, - 'tag_id' => $importJob->tag_id, - 'tag_name' => null === $importJob->tag_id ? null : $importJob->tag->tag, - 'report_txt' => (string) trans('import.unknown_import_result'), - 'download_config' => false, - 'download_config_text' => '', - ]; - - if ('file' === $importJob->provider) { - $json['download_config'] = true; - $json['download_config_text'] - = trans('import.should_download_config', ['route' => route('import.job.download', [$importJob->key])]) . ' ' - . trans('import.share_config_file'); - } - - // if count is zero: - if (null !== $importJob->tag_id) { - $count = $this->repository->countByTag($importJob); - } - if (0 === $count) { - $json['report_txt'] = (string) trans('import.result_no_transactions'); - } - if (1 === $count && null !== $importJob->tag_id) { - $json['report_txt'] = trans( - 'import.result_one_transaction', - ['route' => route('tags.show', [$importJob->tag_id, 'all']), 'tag' => $importJob->tag->tag] - ); - } - if ($count > 1 && null !== $importJob->tag_id) { - $json['report_txt'] = trans( - 'import.result_many_transactions', - ['count' => $count, 'route' => route('tags.show', [$importJob->tag_id, 'all']), 'tag' => $importJob->tag->tag] - ); - } - - return response()->json($json); - } - - /** - * Calls to start the job. - * - * @param ImportJob $importJob - * - * @return JsonResponse - */ - public function start(ImportJob $importJob): JsonResponse - { - Log::info('Now in JobStatusController::start'); - // catch impossible status: - $allowed = ['ready_to_run', 'need_job_config']; - - if (null !== $importJob && !in_array($importJob->status, $allowed, true)) { - Log::error(sprintf('Job is not ready. Status should be in array, but is %s', $importJob->status), $allowed); - $this->repository->setStatus($importJob, 'error'); - - return response()->json( - ['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "ready_to_run" instead of "%s".', $importJob->status)] - ); - } - $importProvider = $importJob->provider; - $key = sprintf('import.routine.%s', $importProvider); - $className = config($key); - if (null === $className || !class_exists($className)) { - // @codeCoverageIgnoreStart - $message = sprintf('Cannot find import routine class for job of type "%s".', $importProvider); - Log::error($message); - - return response()->json( - ['status' => 'NOK', 'message' => $message] - ); - // @codeCoverageIgnoreEnd - } - - /** @var RoutineInterface $routine */ - $routine = app($className); - $routine->setImportJob($importJob); - - Log::debug(sprintf('Created class of type %s', $className)); - - try { - Log::debug(sprintf('Try to call %s:run()', $className)); - $routine->run(); - } catch (FireflyException|Exception $e) { - $message = 'The import routine crashed: ' . $e->getMessage(); - Log::error($message); - Log::error($e->getTraceAsString()); - - // set job errored out: - $this->repository->setStatus($importJob, 'error'); - - return response()->json(['status' => 'NOK', 'message' => $message]); - } - - // expect nothing from routine, just return OK to user. - Log::info('Now finished with JobStatusController::start'); - - return response()->json(['status' => 'OK', 'message' => 'stage_finished']); - } - - /** - * Store does three things: - * - * - Store the transactions. - * - Add them to a tag. - * - * @param ImportJob $importJob - * - * @return JsonResponse - */ - public function store(ImportJob $importJob): JsonResponse - { - Log::info('Now in JobStatusController::store'); - // catch impossible status: - $allowed = ['provider_finished', 'storing_data']; - if (null !== $importJob && !in_array($importJob->status, $allowed, true)) { - Log::error(sprintf('Job is not ready. Status should be in array, but is %s', $importJob->status), $allowed); - - return response()->json( - ['status' => 'NOK', 'message' => sprintf('JobStatusController::start expects status "provider_finished" instead of "%s".', $importJob->status)] - ); - } - - // set job to be storing data: - $this->repository->setStatus($importJob, 'storing_data'); - - try { - $this->storeTransactions($importJob); - } catch (FireflyException $e) { - $message = 'The import storage routine crashed: ' . $e->getMessage(); - Log::error($message); - Log::error($e->getTraceAsString()); - - // set job errored out: - $this->repository->setStatus($importJob, 'error'); - - return response()->json(['status' => 'NOK', 'message' => $message]); - } - // set storage to be finished: - $this->repository->setStatus($importJob, 'storage_finished'); - - Log::info('Now finished with JobStatusController::start'); - - // expect nothing from routine, just return OK to user. - return response()->json(['status' => 'OK', 'message' => 'storage_finished']); - } -} diff --git a/app/Http/Controllers/Import/PrerequisitesController.php b/app/Http/Controllers/Import/PrerequisitesController.php deleted file mode 100644 index e2f361c5ba..0000000000 --- a/app/Http/Controllers/Import/PrerequisitesController.php +++ /dev/null @@ -1,177 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Http\Controllers\Import; - -use FireflyIII\Http\Controllers\Controller; -use FireflyIII\Import\Prerequisites\PrerequisitesInterface; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\User; -use Illuminate\Contracts\View\Factory; -use Illuminate\Http\RedirectResponse; -use Illuminate\Http\Request; -use Illuminate\Routing\Redirector; -use Illuminate\View\View; -use Log; - -/** - * Class PrerequisitesController - * - * @deprecated - * @codeCoverageIgnore - */ -class PrerequisitesController extends Controller -{ - - /** @var ImportJobRepositoryInterface The import job repository */ - private $repository; - - /** - * PrerequisitesController constructor. - */ - public function __construct() - { - parent::__construct(); - - $this->middleware( - function ($request, $next) { - app('view')->share('mainTitleIcon', 'fa-archive'); - app('view')->share('title', (string) trans('firefly.import_index_title')); - app('view')->share('subTitleIcon', 'fa-check'); - - $this->repository = app(ImportJobRepositoryInterface::class); - - return $next($request); - } - ); - } - - /** - * This method will process and store import provider global prerequisites - * such as API keys. - * - * @param string $importProvider - * @param ImportJob $importJob - * - * @return Factory|RedirectResponse|Redirector|View - */ - public function index(string $importProvider, ImportJob $importJob = null) - { - // catch impossible status: - $allowed = ['new']; - if (null !== $importJob && !in_array($importJob->status, $allowed, true)) { - Log::error(sprintf('Job has state "%s" but this Prerequisites::index() only accepts %s', $importJob->status, json_encode($allowed))); - session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)])); - - return redirect(route('import.index')); - } - - app('view')->share('subTitle', (string) trans('import.prerequisites_breadcrumb_' . $importProvider)); - $class = (string) config(sprintf('import.prerequisites.%s', $importProvider)); - /** @var User $user */ - $user = auth()->user(); - /** @var PrerequisitesInterface $object */ - $object = app($class); - $object->setUser($user); - - if (null !== $importJob && $object->isComplete()) { - // update job: - $this->repository->setStatus($importJob, 'has_prereq'); - - // redirect to job config: - return redirect(route('import.job.configuration.index', [$importJob->key])); - } - - - $view = $object->getView(); - $parameters = ['title' => (string) trans('firefly.import_index_title'), 'mainTitleIcon' => 'fa-archive', 'importJob' => $importJob]; - $parameters = array_merge($object->getViewParameters(), $parameters); - - return view($view, $parameters); - } - - /** - * This method processes the prerequisites the user has entered in the previous step. - * - * Whatever storePrerequisites does, it should make sure that the system is ready to continue immediately. So - * no extra calls or stuff, except maybe to open a session - * - * @param Request $request - * @param string $importProvider - * @param ImportJob $importJob - * - * @return RedirectResponse|Redirector - * @see PrerequisitesInterface::storePrerequisites - * - */ - public function post(Request $request, string $importProvider, ImportJob $importJob = null) - { - Log::debug(sprintf('Now in postPrerequisites for %s', $importProvider)); - - // catch impossible status: - $allowed = ['new']; - if (null !== $importJob && !in_array($importJob->status, $allowed, true)) { - Log::error(sprintf('Job has state "%s" but this Prerequisites::post() only accepts %s', $importJob->status, json_encode($allowed))); - session()->flash('error', (string) trans('import.bad_job_status', ['status' => e($importJob->status)])); - - return redirect(route('import.index')); - } - - - $class = (string) config(sprintf('import.prerequisites.%s', $importProvider)); - /** @var User $user */ - $user = auth()->user(); - /** @var PrerequisitesInterface $object */ - $object = app($class); - $object->setUser($user); - Log::debug('Going to store entered prerequisites.'); - // store post data - $data = $request->all(); - $result = $object->storePrerequisites($data); - Log::debug(sprintf('Result of storePrerequisites has message count: %d', $result->count())); - - if ($result->count() > 0) { - $request->session()->flash('error', e($result->first())); - - // redirect back to job, if has job: - return redirect(route('import.prerequisites.index', [$importProvider, $importJob->key ?? '']))->withInput(); - } - - // session flash! - $request->session()->flash('success', (string) trans('import.prerequisites_saved_for_' . $importProvider)); - - // if has job, redirect to global config for provider - // if no job, back to index! - if (null === $importJob) { - return redirect(route('import.index')); - } - - // update job: - $this->repository->setStatus($importJob, 'has_prereq'); - - // redirect to job config: - return redirect(route('import.job.configuration.index', [$importJob->key])); - - - } -} diff --git a/app/Http/Controllers/JavascriptController.php b/app/Http/Controllers/JavascriptController.php index 5bd6bc9874..ba293e76c7 100644 --- a/app/Http/Controllers/JavascriptController.php +++ b/app/Http/Controllers/JavascriptController.php @@ -22,6 +22,7 @@ declare(strict_types=1); namespace FireflyIII\Http\Controllers; +use Carbon\Carbon; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; use FireflyIII\Models\TransactionCurrency; @@ -95,6 +96,30 @@ class JavascriptController extends Controller ->header('Content-Type', 'text/javascript'); } + /** + * Bit of a hack but OK. + * + * @param Request $request + * + * @return Response + */ + public function variablesV2(Request $request): Response + { + /** @var Carbon $start */ + $start = clone session('start', Carbon::now()->startOfMonth()); + /** @var Carbon $end */ + $end = clone session('end', Carbon::now()->endOfMonth()); + + $data = [ + 'start' => $start->format('Y-m-d'), + 'end' => $end->format('Y-m-d'), + ]; + + return response() + ->view('javascript.variables', $data) + ->header('Content-Type', 'text/javascript'); + } + /** * Show some common variables to be used in scripts. * diff --git a/app/Http/Controllers/Json/AutoCompleteController.php b/app/Http/Controllers/Json/AutoCompleteController.php index 820d4ed711..4a6a204d78 100644 --- a/app/Http/Controllers/Json/AutoCompleteController.php +++ b/app/Http/Controllers/Json/AutoCompleteController.php @@ -27,6 +27,7 @@ use Carbon\Carbon; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Models\Account; use FireflyIII\Models\AccountType; +use FireflyIII\Models\ObjectGroup; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; @@ -35,6 +36,7 @@ use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; +use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; use FireflyIII\Repositories\Tag\TagRepositoryInterface; use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; @@ -342,6 +344,34 @@ class AutoCompleteController extends Controller return response()->json($return); } + /** + * An auto-complete specifically for expense accounts, used when mass updating mostly. + * + * @param Request $request + * + * @return JsonResponse + */ + public function objectGroups(Request $request): JsonResponse + { + $search = $request->get('search'); + + /** @var ObjectGroupRepositoryInterface $repository */ + $repository = app(ObjectGroupRepositoryInterface::class); + + $return = []; + $result = $repository->search((string) $search); + + /** @var ObjectGroup $account */ + foreach ($result as $objectGroup) { + $return[] = [ + 'id' => $objectGroup->id, + 'title' => $objectGroup->title, + ]; + } + + return response()->json($return); + } + /** * @return JsonResponse * @codeCoverageIgnore diff --git a/app/Http/Controllers/ObjectGroup/DeleteController.php b/app/Http/Controllers/ObjectGroup/DeleteController.php new file mode 100644 index 0000000000..293d953ba6 --- /dev/null +++ b/app/Http/Controllers/ObjectGroup/DeleteController.php @@ -0,0 +1,70 @@ +middleware( + function ($request, $next) { + app('view')->share('mainTitleIcon', 'fa-envelope-o'); + app('view')->share('title', (string) trans('firefly.object_groups_page_title')); + + $this->repository = app(ObjectGroupRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Delete a piggy bank. + * + * @param ObjectGroup $objectGroup + */ + public function delete(ObjectGroup $objectGroup) + { + $subTitle = (string) trans('firefly.delete_object_group', ['title' => $objectGroup->title]); + $piggyBanks = $objectGroup->piggyBanks()->count(); + + // put previous url in session + $this->rememberPreviousUri('object-groups.delete.uri'); + + return view('object-groups.delete', compact('objectGroup', 'subTitle', 'piggyBanks')); + } + + /** + * Destroy the piggy bank. + * + * @param ObjectGroup $objectGroup + */ + public function destroy(ObjectGroup $objectGroup): RedirectResponse + { + session()->flash('success', (string) trans('firefly.deleted_object_group', ['title' => $objectGroup->title])); + app('preferences')->mark(); + $this->repository->destroy($objectGroup); + + return redirect($this->getPreviousUri('object-groups.delete.uri')); + } + +} diff --git a/app/Http/Controllers/ObjectGroup/EditController.php b/app/Http/Controllers/ObjectGroup/EditController.php new file mode 100644 index 0000000000..d760007802 --- /dev/null +++ b/app/Http/Controllers/ObjectGroup/EditController.php @@ -0,0 +1,87 @@ +middleware( + function ($request, $next) { + app('view')->share('mainTitleIcon', 'fa-envelope-o'); + app('view')->share('title', (string) trans('firefly.object_groups_page_title')); + + $this->repository = app(ObjectGroupRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Edit an object group. + * + * @param ObjectGroup $objectGroup + */ + public function edit(ObjectGroup $objectGroup) + { + $subTitle = (string) trans('firefly.edit_object_group', ['title' => $objectGroup->title]); + $subTitleIcon = 'fa-pencil'; + $targetDate = null; + $startDate = null; + + if (true !== session('object-groups.edit.fromUpdate')) { + $this->rememberPreviousUri('object-groups.edit.uri'); + } + session()->forget('object-groups.edit.fromUpdate'); + + return view('object-groups.edit', compact('subTitle', 'subTitleIcon', 'objectGroup')); + } + + + /** + * Update a piggy bank. + * + * @param ObjectGroupFormRequest $request + * @param ObjectGroup $objectGroup + */ + public function update(ObjectGroupFormRequest $request, ObjectGroup $objectGroup) + { + $data = $request->getObjectGroupData(); + $piggyBank = $this->repository->update($objectGroup, $data); + + session()->flash('success', (string) trans('firefly.updated_object_group', ['title' => $objectGroup->title])); + app('preferences')->mark(); + + $redirect = redirect($this->getPreviousUri('object-groups.edit.uri')); + + if (1 === (int) $request->get('return_to_edit')) { + // @codeCoverageIgnoreStart + session()->put('object-groups.edit.fromUpdate', true); + + $redirect = redirect(route('object-groups.edit', [$piggyBank->id])); + // @codeCoverageIgnoreEnd + } + + return $redirect; + } +} diff --git a/app/Http/Controllers/ObjectGroup/IndexController.php b/app/Http/Controllers/ObjectGroup/IndexController.php new file mode 100644 index 0000000000..6185dade42 --- /dev/null +++ b/app/Http/Controllers/ObjectGroup/IndexController.php @@ -0,0 +1,65 @@ +middleware( + function ($request, $next) { + app('view')->share('mainTitleIcon', 'fa-envelope-o'); + app('view')->share('title', (string) trans('firefly.object_groups_page_title')); + $this->repository = app(ObjectGroupRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * @return \Illuminate\Contracts\Foundation\Application|\Illuminate\Contracts\View\Factory|\Illuminate\View\View + */ + public function index() + { + $this->repository->sort(); + $subTitle = (string) trans('firefly.object_groups_index'); + $objectGroups = $this->repository->get(); + + return view('object-groups.index', compact('subTitle', 'objectGroups')); + } + + /** + * @param ObjectGroup $objectGroup + */ + public function setOrder(Request $request, ObjectGroup $objectGroup) + { + Log::debug(sprintf('Found object group #%d "%s"', $objectGroup->id, $objectGroup->title)); + $newOrder = (int) $request->get('order'); + $this->repository->setOrder($objectGroup, $newOrder); + + return response()->json([]); + } + +} diff --git a/app/Http/Controllers/PiggyBank/AmountController.php b/app/Http/Controllers/PiggyBank/AmountController.php new file mode 100644 index 0000000000..eb82627d01 --- /dev/null +++ b/app/Http/Controllers/PiggyBank/AmountController.php @@ -0,0 +1,201 @@ +middleware( + function ($request, $next) { + app('view')->share('title', (string) trans('firefly.piggyBanks')); + app('view')->share('mainTitleIcon', 'fa-bullseye'); + + $this->piggyRepos = app(PiggyBankRepositoryInterface::class); + $this->accountRepos = app(AccountRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Add money to piggy bank. + * + * @param PiggyBank $piggyBank + * + * @return Factory|View + */ + public function add(PiggyBank $piggyBank) + { + $leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, new Carbon); + $savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank); + $leftToSave = bcsub($piggyBank->targetamount, $savedSoFar); + $maxAmount = min($leftOnAccount, $leftToSave); + $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); + + return view('piggy-banks.add', compact('piggyBank', 'maxAmount', 'currency')); + } + + /** + * Add money to piggy bank (for mobile devices). + * + * @param PiggyBank $piggyBank + * + * @return Factory|View + */ + public function addMobile(PiggyBank $piggyBank) + { + /** @var Carbon $date */ + $date = session('end', new Carbon); + $leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $date); + $savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank); + $leftToSave = bcsub($piggyBank->targetamount, $savedSoFar); + $maxAmount = min($leftOnAccount, $leftToSave); + $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); + + return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount', 'currency')); + } + + /** + * Add money to piggy bank. + * + * @param Request $request + * @param PiggyBank $piggyBank + * + * @return RedirectResponse + */ + public function postAdd(Request $request, PiggyBank $piggyBank): RedirectResponse + { + $amount = $request->get('amount') ?? '0'; + $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); + // if amount is negative, make positive and continue: + if (-1 === bccomp($amount, '0')) { + $amount = bcmul($amount, '-1'); + } + if ($this->piggyRepos->canAddAmount($piggyBank, $amount)) { + $this->piggyRepos->addAmount($piggyBank, $amount); + session()->flash( + 'success', + (string) trans( + 'firefly.added_amount_to_piggy', + ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name] + ) + ); + app('preferences')->mark(); + + return redirect(route('piggy-banks.index')); + } + + Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.'); + session()->flash( + 'error', + (string) trans( + 'firefly.cannot_add_amount_piggy', + ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)] + ) + ); + + return redirect(route('piggy-banks.index')); + } + + /** + * Remove money from piggy bank. + * + * @param Request $request + * @param PiggyBank $piggyBank + * + * @return RedirectResponse + */ + public function postRemove(Request $request, PiggyBank $piggyBank): RedirectResponse + { + $amount = $request->get('amount') ?? '0'; + $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); + // if amount is negative, make positive and continue: + if (-1 === bccomp($amount, '0')) { + $amount = bcmul($amount, '-1'); + } + if ($this->piggyRepos->canRemoveAmount($piggyBank, $amount)) { + $this->piggyRepos->removeAmount($piggyBank, $amount); + session()->flash( + 'success', + (string) trans( + 'firefly.removed_amount_from_piggy', + ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name] + ) + ); + app('preferences')->mark(); + + return redirect(route('piggy-banks.index')); + } + + $amount = (string) round($request->get('amount'), 12); + + session()->flash( + 'error', + (string) trans( + 'firefly.cannot_remove_from_piggy', + ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)] + ) + ); + + return redirect(route('piggy-banks.index')); + } + + /** + * Remove money from piggy bank form. + * + * @param PiggyBank $piggyBank + * + * @return Factory|View + */ + public function remove(PiggyBank $piggyBank) + { + $repetition = $this->piggyRepos->getRepetition($piggyBank); + $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); + + return view('piggy-banks.remove', compact('piggyBank', 'repetition', 'currency')); + } + + /** + * Remove money from piggy bank (for mobile devices). + * + * @param PiggyBank $piggyBank + * + * @return Factory|View + */ + public function removeMobile(PiggyBank $piggyBank) + { + $repetition = $this->piggyRepos->getRepetition($piggyBank); + $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); + + return view('piggy-banks.remove-mobile', compact('piggyBank', 'repetition', 'currency')); + } +} diff --git a/app/Http/Controllers/PiggyBank/CreateController.php b/app/Http/Controllers/PiggyBank/CreateController.php new file mode 100644 index 0000000000..de7c18ff72 --- /dev/null +++ b/app/Http/Controllers/PiggyBank/CreateController.php @@ -0,0 +1,112 @@ +middleware( + function ($request, $next) { + app('view')->share('title', (string) trans('firefly.piggyBanks')); + app('view')->share('mainTitleIcon', 'fa-bullseye'); + + $this->attachments = app(AttachmentHelperInterface::class); + $this->piggyRepos = app(PiggyBankRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Create a piggy bank. + * + * @return Factory|View + */ + public function create() + { + $subTitle = (string) trans('firefly.new_piggy_bank'); + $subTitleIcon = 'fa-plus'; + + // put previous url in session if not redirect from store (not "create another"). + if (true !== session('piggy-banks.create.fromStore')) { + $this->rememberPreviousUri('piggy-banks.create.uri'); + } + session()->forget('piggy-banks.create.fromStore'); + + return view('piggy-banks.create', compact('subTitle', 'subTitleIcon')); + } + + + /** + * Store a new piggy bank. + * + * @param PiggyBankFormRequest $request + * + * @return RedirectResponse|Redirector + */ + public function store(PiggyBankFormRequest $request) + { + $data = $request->getPiggyBankData(); + if (null === $data['startdate']) { + $data['startdate'] = new Carbon; + } + $piggyBank = $this->piggyRepos->store($data); + + session()->flash('success', (string) trans('firefly.stored_piggy_bank', ['name' => $piggyBank->name])); + app('preferences')->mark(); + + // store attachment(s): + /** @var array $files */ + $files = $request->hasFile('attachments') ? $request->file('attachments') : null; + if (null !== $files && !auth()->user()->hasRole('demo')) { + $this->attachments->saveAttachmentsForModel($piggyBank, $files); + } + if (null !== $files && auth()->user()->hasRole('demo')) { + session()->flash('info', (string) trans('firefly.no_att_demo_user')); + } + + if (count($this->attachments->getMessages()->get('attachments')) > 0) { + $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore + } + + + $redirect = redirect($this->getPreviousUri('piggy-banks.create.uri')); + + if (1 === (int) $request->get('create_another')) { + // @codeCoverageIgnoreStart + session()->put('piggy-banks.create.fromStore', true); + + $redirect = redirect(route('piggy-banks.create'))->withInput(); + // @codeCoverageIgnoreEnd + } + + return $redirect; + } +} diff --git a/app/Http/Controllers/PiggyBank/DeleteController.php b/app/Http/Controllers/PiggyBank/DeleteController.php new file mode 100644 index 0000000000..3db81000b8 --- /dev/null +++ b/app/Http/Controllers/PiggyBank/DeleteController.php @@ -0,0 +1,75 @@ +middleware( + function ($request, $next) { + app('view')->share('title', (string) trans('firefly.piggyBanks')); + app('view')->share('mainTitleIcon', 'fa-bullseye'); + + $this->piggyRepos = app(PiggyBankRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Delete a piggy bank. + * + * @param PiggyBank $piggyBank + * + * @return Factory|View + */ + public function delete(PiggyBank $piggyBank) + { + $subTitle = (string) trans('firefly.delete_piggy_bank', ['name' => $piggyBank->name]); + + // put previous url in session + $this->rememberPreviousUri('piggy-banks.delete.uri'); + + return view('piggy-banks.delete', compact('piggyBank', 'subTitle')); + } + + /** + * Destroy the piggy bank. + * + * @param PiggyBank $piggyBank + * + * @return RedirectResponse + */ + public function destroy(PiggyBank $piggyBank): RedirectResponse + { + session()->flash('success', (string) trans('firefly.deleted_piggy_bank', ['name' => $piggyBank->name])); + app('preferences')->mark(); + $this->piggyRepos->destroy($piggyBank); + + return redirect($this->getPreviousUri('piggy-banks.delete.uri')); + } +} diff --git a/app/Http/Controllers/PiggyBank/EditController.php b/app/Http/Controllers/PiggyBank/EditController.php new file mode 100644 index 0000000000..2ed18713a3 --- /dev/null +++ b/app/Http/Controllers/PiggyBank/EditController.php @@ -0,0 +1,133 @@ +middleware( + function ($request, $next) { + app('view')->share('title', (string) trans('firefly.piggyBanks')); + app('view')->share('mainTitleIcon', 'fa-bullseye'); + + $this->attachments = app(AttachmentHelperInterface::class); + $this->piggyRepos = app(PiggyBankRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Edit a piggy bank. + * + * @param PiggyBank $piggyBank + * + * @return Factory|View + */ + public function edit(PiggyBank $piggyBank) + { + $subTitle = (string) trans('firefly.update_piggy_title', ['name' => $piggyBank->name]); + $subTitleIcon = 'fa-pencil'; + $targetDate = null; + $startDate = null; + $note = $piggyBank->notes()->first(); + // Flash some data to fill the form. + if (null !== $piggyBank->targetdate) { + $targetDate = $piggyBank->targetdate->format('Y-m-d'); + } + if (null !== $piggyBank->startdate) { + $startDate = $piggyBank->startdate->format('Y-m-d'); + } + + $preFilled = ['name' => $piggyBank->name, + 'account_id' => $piggyBank->account_id, + 'targetamount' => $piggyBank->targetamount, + 'targetdate' => $targetDate, + 'startdate' => $startDate, + 'object_group' => $piggyBank->objectGroups->first() ? $piggyBank->objectGroups->first()->title : '', + 'notes' => null === $note ? '' : $note->text, + ]; + session()->flash('preFilled', $preFilled); + + // put previous url in session if not redirect from store (not "return_to_edit"). + if (true !== session('piggy-banks.edit.fromUpdate')) { + $this->rememberPreviousUri('piggy-banks.edit.uri'); + } + session()->forget('piggy-banks.edit.fromUpdate'); + + return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'preFilled')); + } + + + /** + * Update a piggy bank. + * + * @param PiggyBankFormRequest $request + * @param PiggyBank $piggyBank + * + * @return RedirectResponse|Redirector + */ + public function update(PiggyBankFormRequest $request, PiggyBank $piggyBank) + { + $data = $request->getPiggyBankData(); + $piggyBank = $this->piggyRepos->update($piggyBank, $data); + + session()->flash('success', (string) trans('firefly.updated_piggy_bank', ['name' => $piggyBank->name])); + app('preferences')->mark(); + + // store new attachment(s): + /** @var array $files */ + $files = $request->hasFile('attachments') ? $request->file('attachments') : null; + if (null !== $files && !auth()->user()->hasRole('demo')) { + $this->attachments->saveAttachmentsForModel($piggyBank, $files); + } + if (null !== $files && auth()->user()->hasRole('demo')) { + session()->flash('info', (string) trans('firefly.no_att_demo_user')); + } + + if (count($this->attachments->getMessages()->get('attachments')) > 0) { + $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore + } + + + $redirect = redirect($this->getPreviousUri('piggy-banks.edit.uri')); + + if (1 === (int) $request->get('return_to_edit')) { + // @codeCoverageIgnoreStart + session()->put('piggy-banks.edit.fromUpdate', true); + + $redirect = redirect(route('piggy-banks.edit', [$piggyBank->id])); + // @codeCoverageIgnoreEnd + } + + return $redirect; + } + +} diff --git a/app/Http/Controllers/PiggyBank/IndexController.php b/app/Http/Controllers/PiggyBank/IndexController.php new file mode 100644 index 0000000000..6ed9abd464 --- /dev/null +++ b/app/Http/Controllers/PiggyBank/IndexController.php @@ -0,0 +1,189 @@ +middleware( + function ($request, $next) { + app('view')->share('title', (string) trans('firefly.piggyBanks')); + app('view')->share('mainTitleIcon', 'fa-bullseye'); + + $this->piggyRepos = app(PiggyBankRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Show overview of all piggy banks. + * TODO complicated + * + * @param Request $request + * + * @return Factory|View + */ + public function index(Request $request) + { + $this->cleanupObjectGroups(); + $this->piggyRepos->correctOrder(); + $collection = $this->piggyRepos->getPiggyBanks(); + $accounts = []; + /** @var Carbon $end */ + $end = session('end', Carbon::now()->endOfMonth()); + + // transform piggies using the transformer: + $parameters = new ParameterBag; + $parameters->set('end', $end); + + // make piggy bank groups: + $piggyBanks = [ + 0 => [ // the index is the order, not the ID. + 'object_group_id' => 0, + 'object_group_title' => (string) trans('firefly.default_group_title_name'), + 'piggy_banks' => [], + ], + ]; + + /** @var PiggyBankTransformer $transformer */ + $transformer = app(PiggyBankTransformer::class); + $transformer->setParameters(new ParameterBag); + + /** @var AccountTransformer $accountTransformer */ + $accountTransformer = app(AccountTransformer::class); + $accountTransformer->setParameters($parameters); + /** @var PiggyBank $piggy */ + foreach ($collection as $piggy) { + $array = $transformer->transform($piggy); + $groupOrder = (int) $array['object_group_order']; + // make group array if necessary: + $piggyBanks[$groupOrder] = $piggyBanks[$groupOrder] ?? [ + 'object_group_id' => $array['object_group_id'], + 'object_group_title' => $array['object_group_title'], + 'piggy_banks' => [], + ]; + + $account = $accountTransformer->transform($piggy->account); + $accountId = (int) $account['id']; + $array['attachments'] = $this->piggyRepos->getAttachments($piggy); + if (!isset($accounts[$accountId])) { + // create new: + $accounts[$accountId] = $account; + + // add some interesting details: + $accounts[$accountId]['left'] = $accounts[$accountId]['current_balance']; + $accounts[$accountId]['saved'] = 0; + $accounts[$accountId]['target'] = 0; + $accounts[$accountId]['to_save'] = 0; + } + + // calculate new interesting fields: + $accounts[$accountId]['left'] -= $array['current_amount']; + $accounts[$accountId]['saved'] += $array['current_amount']; + $accounts[$accountId]['target'] += $array['target_amount']; + $accounts[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']); + $array['account_name'] = $account['name']; + $piggyBanks[$groupOrder]['piggy_banks'][] = $array; + } + // do a bunch of summaries. + $piggyBanks = $this->makeSums($piggyBanks); + + ksort($piggyBanks); + + return view('piggy-banks.index', compact('piggyBanks', 'accounts')); + } + + /** + * @param array $piggyBanks + * + * @return array + */ + private function makeSums(array $piggyBanks): array + { + $sums = []; + foreach ($piggyBanks as $groupOrder => $group) { + $groupId = $group['object_group_id']; + foreach ($group['piggy_banks'] as $piggy) { + $currencyId = $piggy['currency_id']; + $sums[$groupId][$currencyId] = $sums[$groupId][$currencyId] ?? [ + 'target' => '0', + 'saved' => '0', + 'left_to_save' => '0', + 'save_per_month' => '0', + 'currency_id' => $currencyId, + 'currency_code' => $piggy['currency_code'], + 'currency_symbol' => $piggy['currency_symbol'], + 'currency_decimal_places' => $piggy['currency_decimal_places'], + ]; + // target_amount + // current_amount + // left_to_save + // save_per_month + $sums[$groupId][$currencyId]['target'] = bcadd($sums[$groupId][$currencyId]['target'], (string) $piggy['target_amount']); + $sums[$groupId][$currencyId]['saved'] = bcadd($sums[$groupId][$currencyId]['saved'], (string) $piggy['current_amount']); + $sums[$groupId][$currencyId]['left_to_save'] = bcadd($sums[$groupId][$currencyId]['left_to_save'], (string) $piggy['left_to_save']); + $sums[$groupId][$currencyId]['save_per_month'] = bcadd($sums[$groupId][$currencyId]['save_per_month'], (string) $piggy['save_per_month']); + } + } + foreach ($piggyBanks as $groupOrder => $group) { + $groupId = $group['object_group_id']; + $piggyBanks[$groupOrder]['sums'] = $sums[$groupId]; + } + + return $piggyBanks; + } + + /** + * Set the order of a piggy bank. + * + * @param Request $request + * @param PiggyBank $piggyBank + * + * @return JsonResponse + */ + public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse + { + $objectGroupTitle = $request->get('objectGroupTitle'); + $newOrder = (int) $request->get('order'); + $this->piggyRepos->setOrder($piggyBank, $newOrder); + if ('' !== $objectGroupTitle) { + $this->piggyRepos->setObjectGroup($piggyBank, $objectGroupTitle); + } + if ('' === $objectGroupTitle) { + $this->piggyRepos->removeObjectGroup($piggyBank); + } + + return response()->json(['data' => 'OK']); + } +} diff --git a/app/Http/Controllers/PiggyBank/ShowController.php b/app/Http/Controllers/PiggyBank/ShowController.php new file mode 100644 index 0000000000..43dec1eea4 --- /dev/null +++ b/app/Http/Controllers/PiggyBank/ShowController.php @@ -0,0 +1,69 @@ +middleware( + function ($request, $next) { + app('view')->share('title', (string) trans('firefly.piggyBanks')); + app('view')->share('mainTitleIcon', 'fa-bullseye'); + + $this->piggyRepos = app(PiggyBankRepositoryInterface::class); + + return $next($request); + } + ); + } + + /** + * Show a single piggy bank. + * + * @param PiggyBank $piggyBank + * + * @return Factory|View + */ + public function show(PiggyBank $piggyBank) + { + /** @var Carbon $end */ + $end = session('end', Carbon::now()->endOfMonth()); + // transform piggies using the transformer: + $parameters = new ParameterBag; + $parameters->set('end', $end); + + /** @var PiggyBankTransformer $transformer */ + $transformer = app(PiggyBankTransformer::class); + $transformer->setParameters($parameters); + $piggy = $transformer->transform($piggyBank); + $events = $this->piggyRepos->getEvents($piggyBank); + $subTitle = $piggyBank->name; + $attachments = $this->piggyRepos->getAttachments($piggyBank); + + return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle', 'piggy', 'attachments')); + } +} diff --git a/app/Http/Controllers/PiggyBankController.php b/app/Http/Controllers/PiggyBankController.php deleted file mode 100644 index d3a6853761..0000000000 --- a/app/Http/Controllers/PiggyBankController.php +++ /dev/null @@ -1,525 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Http\Controllers; - -use Carbon\Carbon; -use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; -use FireflyIII\Http\Requests\PiggyBankFormRequest; -use FireflyIII\Models\PiggyBank; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; -use FireflyIII\Transformers\AccountTransformer; -use FireflyIII\Transformers\PiggyBankTransformer; -use Illuminate\Contracts\View\Factory; -use Illuminate\Http\JsonResponse; -use Illuminate\Http\RedirectResponse; -use Illuminate\Http\Request; -use Illuminate\Pagination\LengthAwarePaginator; -use Illuminate\Routing\Redirector; -use Illuminate\Support\Collection; -use Illuminate\View\View; -use Log; -use Symfony\Component\HttpFoundation\ParameterBag; - -/** - * Class PiggyBankController. - * - */ -class PiggyBankController extends Controller -{ - - /** @var AccountRepositoryInterface The account repository */ - private $accountRepos; - /** @var CurrencyRepositoryInterface The currency repository */ - private $currencyRepos; - /** @var PiggyBankRepositoryInterface Piggy bank repository. */ - private $piggyRepos; - - /** @var AttachmentHelperInterface Helper for attachments. */ - private $attachments; - - /** - * PiggyBankController constructor. - * - * @codeCoverageIgnore - */ - public function __construct() - { - parent::__construct(); - - $this->middleware( - function ($request, $next) { - app('view')->share('title', (string) trans('firefly.piggyBanks')); - app('view')->share('mainTitleIcon', 'fa-bullseye'); - - $this->attachments = app(AttachmentHelperInterface::class); - $this->piggyRepos = app(PiggyBankRepositoryInterface::class); - $this->currencyRepos = app(CurrencyRepositoryInterface::class); - $this->accountRepos = app(AccountRepositoryInterface::class); - - return $next($request); - } - ); - } - - /** - * Add money to piggy bank. - * - * @param PiggyBank $piggyBank - * - * @return Factory|View - */ - public function add(PiggyBank $piggyBank) - { - $leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, new Carbon); - $savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank); - $leftToSave = bcsub($piggyBank->targetamount, $savedSoFar); - $maxAmount = min($leftOnAccount, $leftToSave); - $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); - - return view('piggy-banks.add', compact('piggyBank', 'maxAmount', 'currency')); - } - - /** - * Add money to piggy bank (for mobile devices). - * - * @param PiggyBank $piggyBank - * - * @return Factory|View - */ - public function addMobile(PiggyBank $piggyBank) - { - /** @var Carbon $date */ - $date = session('end', new Carbon); - $leftOnAccount = $this->piggyRepos->leftOnAccount($piggyBank, $date); - $savedSoFar = $this->piggyRepos->getCurrentAmount($piggyBank); - $leftToSave = bcsub($piggyBank->targetamount, $savedSoFar); - $maxAmount = min($leftOnAccount, $leftToSave); - $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); - - return view('piggy-banks.add-mobile', compact('piggyBank', 'maxAmount', 'currency')); - } - - /** - * Create a piggy bank. - * - * @return Factory|View - */ - public function create() - { - $subTitle = (string) trans('firefly.new_piggy_bank'); - $subTitleIcon = 'fa-plus'; - - // put previous url in session if not redirect from store (not "create another"). - if (true !== session('piggy-banks.create.fromStore')) { - $this->rememberPreviousUri('piggy-banks.create.uri'); - } - session()->forget('piggy-banks.create.fromStore'); - - return view('piggy-banks.create', compact('subTitle', 'subTitleIcon')); - } - - /** - * Delete a piggy bank. - * - * @param PiggyBank $piggyBank - * - * @return Factory|View - */ - public function delete(PiggyBank $piggyBank) - { - $subTitle = (string) trans('firefly.delete_piggy_bank', ['name' => $piggyBank->name]); - - // put previous url in session - $this->rememberPreviousUri('piggy-banks.delete.uri'); - - return view('piggy-banks.delete', compact('piggyBank', 'subTitle')); - } - - /** - * Destroy the piggy bank. - * - * @param PiggyBank $piggyBank - * - * @return RedirectResponse - */ - public function destroy(PiggyBank $piggyBank): RedirectResponse - { - session()->flash('success', (string) trans('firefly.deleted_piggy_bank', ['name' => $piggyBank->name])); - app('preferences')->mark(); - $this->piggyRepos->destroy($piggyBank); - - return redirect($this->getPreviousUri('piggy-banks.delete.uri')); - } - - /** - * Edit a piggy bank. - * - * @param PiggyBank $piggyBank - * - * @return Factory|View - */ - public function edit(PiggyBank $piggyBank) - { - $subTitle = (string) trans('firefly.update_piggy_title', ['name' => $piggyBank->name]); - $subTitleIcon = 'fa-pencil'; - $targetDate = null; - $startDate = null; - $note = $piggyBank->notes()->first(); - // Flash some data to fill the form. - if (null !== $piggyBank->targetdate) { - $targetDate = $piggyBank->targetdate->format('Y-m-d'); - } - if (null !== $piggyBank->startdate) { - $startDate = $piggyBank->startdate->format('Y-m-d'); - } - - $preFilled = ['name' => $piggyBank->name, - 'account_id' => $piggyBank->account_id, - 'targetamount' => $piggyBank->targetamount, - 'targetdate' => $targetDate, - 'startdate' => $startDate, - 'notes' => null === $note ? '' : $note->text, - ]; - session()->flash('preFilled', $preFilled); - - // put previous url in session if not redirect from store (not "return_to_edit"). - if (true !== session('piggy-banks.edit.fromUpdate')) { - $this->rememberPreviousUri('piggy-banks.edit.uri'); - } - session()->forget('piggy-banks.edit.fromUpdate'); - - return view('piggy-banks.edit', compact('subTitle', 'subTitleIcon', 'piggyBank', 'preFilled')); - } - - /** - * Show overview of all piggy banks. - * - * @param Request $request - * - * @return Factory|View - */ - public function index(Request $request) - { - $this->piggyRepos->correctOrder(); - $collection = $this->piggyRepos->getPiggyBanks(); - $total = $collection->count(); - $page = 0 === (int) $request->get('page') ? 1 : (int) $request->get('page'); - $pageSize = (int) app('preferences')->get('listPageSize', 50)->data; - $accounts = []; - /** @var Carbon $end */ - $end = session('end', Carbon::now()->endOfMonth()); - - // transform piggies using the transformer: - $parameters = new ParameterBag; - $parameters->set('end', $end); - $transformed = new Collection; - - /** @var PiggyBankTransformer $transformer */ - $transformer = app(PiggyBankTransformer::class); - $transformer->setParameters(new ParameterBag); - - /** @var AccountTransformer $accountTransformer */ - $accountTransformer = app(AccountTransformer::class); - $accountTransformer->setParameters($parameters); - /** @var PiggyBank $piggy */ - foreach ($collection as $piggy) { - $array = $transformer->transform($piggy); - $account = $accountTransformer->transform($piggy->account); - $accountId = (int) $account['id']; - $array['attachments'] = $this->piggyRepos->getAttachments($piggy); - if (!isset($accounts[$accountId])) { - // create new: - $accounts[$accountId] = $account; - - // add some interesting details: - $accounts[$accountId]['left'] = $accounts[$accountId]['current_balance']; - $accounts[$accountId]['saved'] = 0; - $accounts[$accountId]['target'] = 0; - $accounts[$accountId]['to_save'] = 0; - } - - // calculate new interesting fields: - $accounts[$accountId]['left'] -= $array['current_amount']; - $accounts[$accountId]['saved'] += $array['current_amount']; - $accounts[$accountId]['target'] += $array['target_amount']; - $accounts[$accountId]['to_save'] += ($array['target_amount'] - $array['current_amount']); - $array['account_name'] = $account['name']; - $transformed->push($array); - } - - $transformed = $transformed->slice(($page - 1) * $pageSize, $pageSize); - $piggyBanks = new LengthAwarePaginator($transformed, $total, $pageSize, $page); - $piggyBanks->setPath(route('piggy-banks.index')); - - return view('piggy-banks.index', compact('piggyBanks', 'accounts')); - } - - /** - * Add money to piggy bank. - * - * @param Request $request - * @param PiggyBank $piggyBank - * - * @return RedirectResponse - */ - public function postAdd(Request $request, PiggyBank $piggyBank): RedirectResponse - { - $amount = $request->get('amount') ?? '0'; - $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); - // if amount is negative, make positive and continue: - if (-1 === bccomp($amount, '0')) { - $amount = bcmul($amount, '-1'); - } - if ($this->piggyRepos->canAddAmount($piggyBank, $amount)) { - $this->piggyRepos->addAmount($piggyBank, $amount); - session()->flash( - 'success', - (string) trans( - 'firefly.added_amount_to_piggy', - ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name] - ) - ); - app('preferences')->mark(); - - return redirect(route('piggy-banks.index')); - } - - Log::error('Cannot add ' . $amount . ' because canAddAmount returned false.'); - session()->flash( - 'error', - (string) trans( - 'firefly.cannot_add_amount_piggy', - ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)] - ) - ); - - return redirect(route('piggy-banks.index')); - } - - /** - * Remove money from piggy bank. - * - * @param Request $request - * @param PiggyBank $piggyBank - * - * @return RedirectResponse - */ - public function postRemove(Request $request, PiggyBank $piggyBank): RedirectResponse - { - $amount = $request->get('amount') ?? '0'; - $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); - // if amount is negative, make positive and continue: - if (-1 === bccomp($amount, '0')) { - $amount = bcmul($amount, '-1'); - } - if ($this->piggyRepos->canRemoveAmount($piggyBank, $amount)) { - $this->piggyRepos->removeAmount($piggyBank, $amount); - session()->flash( - 'success', - (string) trans( - 'firefly.removed_amount_from_piggy', - ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => $piggyBank->name] - ) - ); - app('preferences')->mark(); - - return redirect(route('piggy-banks.index')); - } - - $amount = (string) round($request->get('amount'), 12); - - session()->flash( - 'error', - (string) trans( - 'firefly.cannot_remove_from_piggy', - ['amount' => app('amount')->formatAnything($currency, $amount, false), 'name' => e($piggyBank->name)] - ) - ); - - return redirect(route('piggy-banks.index')); - } - - /** - * Remove money from piggy bank form. - * - * @param PiggyBank $piggyBank - * - * @return Factory|View - */ - public function remove(PiggyBank $piggyBank) - { - $repetition = $this->piggyRepos->getRepetition($piggyBank); - $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); - - return view('piggy-banks.remove', compact('piggyBank', 'repetition', 'currency')); - } - - /** - * Remove money from piggy bank (for mobile devices). - * - * @param PiggyBank $piggyBank - * - * @return Factory|View - */ - public function removeMobile(PiggyBank $piggyBank) - { - $repetition = $this->piggyRepos->getRepetition($piggyBank); - $currency = $this->accountRepos->getAccountCurrency($piggyBank->account) ?? app('amount')->getDefaultCurrency(); - - return view('piggy-banks.remove-mobile', compact('piggyBank', 'repetition', 'currency')); - } - - /** - * Set the order of a piggy bank. - * - * @param Request $request - * @param PiggyBank $piggyBank - * - * @return JsonResponse - */ - public function setOrder(Request $request, PiggyBank $piggyBank): JsonResponse - { - $newOrder = (int) $request->get('order'); - $this->piggyRepos->setOrder($piggyBank, $newOrder); - - return response()->json(['data' => 'OK']); - } - - /** - * Show a single piggy bank. - * - * @param PiggyBank $piggyBank - * - * @return Factory|View - */ - public function show(PiggyBank $piggyBank) - { - /** @var Carbon $end */ - $end = session('end', Carbon::now()->endOfMonth()); - // transform piggies using the transformer: - $parameters = new ParameterBag; - $parameters->set('end', $end); - - /** @var PiggyBankTransformer $transformer */ - $transformer = app(PiggyBankTransformer::class); - $transformer->setParameters($parameters); - $piggy = $transformer->transform($piggyBank); - $events = $this->piggyRepos->getEvents($piggyBank); - $subTitle = $piggyBank->name; - $attachments = $this->piggyRepos->getAttachments($piggyBank); - - return view('piggy-banks.show', compact('piggyBank', 'events', 'subTitle', 'piggy', 'attachments')); - } - - /** - * Store a new piggy bank. - * - * @param PiggyBankFormRequest $request - * - * @return RedirectResponse|Redirector - */ - public function store(PiggyBankFormRequest $request) - { - $data = $request->getPiggyBankData(); - if (null === $data['startdate']) { - $data['startdate'] = new Carbon; - } - $piggyBank = $this->piggyRepos->store($data); - - session()->flash('success', (string) trans('firefly.stored_piggy_bank', ['name' => $piggyBank->name])); - app('preferences')->mark(); - - // store attachment(s): - /** @var array $files */ - $files = $request->hasFile('attachments') ? $request->file('attachments') : null; - if (null !== $files && !auth()->user()->hasRole('demo')) { - $this->attachments->saveAttachmentsForModel($piggyBank, $files); - } - if (null !== $files && auth()->user()->hasRole('demo')) { - session()->flash('info',(string)trans('firefly.no_att_demo_user')); - } - - if (count($this->attachments->getMessages()->get('attachments')) > 0) { - $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore - } - - - $redirect = redirect($this->getPreviousUri('piggy-banks.create.uri')); - - if (1 === (int) $request->get('create_another')) { - // @codeCoverageIgnoreStart - session()->put('piggy-banks.create.fromStore', true); - - $redirect = redirect(route('piggy-banks.create'))->withInput(); - // @codeCoverageIgnoreEnd - } - - return $redirect; - } - - /** - * Update a piggy bank. - * - * @param PiggyBankFormRequest $request - * @param PiggyBank $piggyBank - * - * @return RedirectResponse|Redirector - */ - public function update(PiggyBankFormRequest $request, PiggyBank $piggyBank) - { - $data = $request->getPiggyBankData(); - $piggyBank = $this->piggyRepos->update($piggyBank, $data); - - session()->flash('success', (string) trans('firefly.updated_piggy_bank', ['name' => $piggyBank->name])); - app('preferences')->mark(); - - // store new attachment(s): - /** @var array $files */ - $files = $request->hasFile('attachments') ? $request->file('attachments') : null; - if (null !== $files && !auth()->user()->hasRole('demo')) { - $this->attachments->saveAttachmentsForModel($piggyBank, $files); - } - if (null !== $files && auth()->user()->hasRole('demo')) { - session()->flash('info',(string)trans('firefly.no_att_demo_user')); - } - - if (count($this->attachments->getMessages()->get('attachments')) > 0) { - $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore - } - - - $redirect = redirect($this->getPreviousUri('piggy-banks.edit.uri')); - - if (1 === (int) $request->get('return_to_edit')) { - // @codeCoverageIgnoreStart - session()->put('piggy-banks.edit.fromUpdate', true); - - $redirect = redirect(route('piggy-banks.edit', [$piggyBank->id])); - // @codeCoverageIgnoreEnd - } - - return $redirect; - } -} diff --git a/app/Http/Controllers/ProfileController.php b/app/Http/Controllers/ProfileController.php index 9c84f76e5a..6cd342aaba 100644 --- a/app/Http/Controllers/ProfileController.php +++ b/app/Http/Controllers/ProfileController.php @@ -61,6 +61,8 @@ class ProfileController extends Controller { use RequestInformation, CreateStuff; + protected bool $externalIdentity; + /** * ProfileController constructor. * @@ -78,6 +80,9 @@ class ProfileController extends Controller return $next($request); } ); + $loginProvider = config('firefly.login_provider'); + $authGuard = config('firefly.authentication_guard'); + $this->externalIdentity = 'eloquent' === $loginProvider || 'remote_user_guard' === $authGuard; $this->middleware(IsDemoUser::class)->except(['index']); $this->middleware(IsSandStormUser::class)->except('index'); @@ -92,13 +97,10 @@ class ProfileController extends Controller */ public function changeEmail(Request $request) { - $loginProvider = config('firefly.login_provider'); - if ('eloquent' !== $loginProvider) { - // @codeCoverageIgnoreStart - $request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)])); + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); return redirect(route('profile.index')); - // @codeCoverageIgnoreEnd } $title = auth()->user()->email; @@ -118,13 +120,10 @@ class ProfileController extends Controller */ public function changePassword(Request $request) { - $loginProvider = config('firefly.login_provider'); - if ('eloquent' !== $loginProvider) { - // @codeCoverageIgnoreStart - $request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)])); + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); return redirect(route('profile.index')); - // @codeCoverageIgnoreEnd } $title = auth()->user()->email; @@ -137,10 +136,17 @@ class ProfileController extends Controller /** * View that generates a 2FA code for the user. * + * @param Request $request + * * @return Factory|View */ - public function code() + public function code(Request $request) { + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } $domain = $this->getDomain(); $secret = null; @@ -192,10 +198,9 @@ class ProfileController extends Controller */ public function confirmEmailChange(UserRepositoryInterface $repository, string $token) { - $loginProvider = config('firefly.login_provider'); - if ('eloquent' !== $loginProvider) { + if ($this->externalIdentity) { // @codeCoverageIgnoreStart - throw new FireflyException('Cannot confirm email change when authentication provider is not local.'); + throw new FireflyException(trans('firefly.external_user_mgt_disabled')); // @codeCoverageIgnoreEnd } // find preference with this token value. @@ -229,15 +234,14 @@ class ProfileController extends Controller * * @param Request $request * - * @return Factory|View + * @return \Illuminate\Contracts\Foundation\Application|RedirectResponse|Redirector */ public function deleteAccount(Request $request) { - $loginProvider = config('firefly.login_provider'); - if ('eloquent' !== $loginProvider) { - // @codeCoverageIgnoreStart - $request->session()->flash('warning', trans('firefly.delete_local_info_only', ['login_provider' => e($loginProvider)])); - // @codeCoverageIgnoreEnd + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); } $title = auth()->user()->email; $subTitle = (string) trans('firefly.delete_account'); @@ -251,8 +255,13 @@ class ProfileController extends Controller * * @return RedirectResponse|Redirector */ - public function deleteCode() + public function deleteCode(Request $request) { + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } /** @var UserRepositoryInterface $repository */ $repository = app(UserRepositoryInterface::class); @@ -271,8 +280,14 @@ class ProfileController extends Controller * * @return RedirectResponse|Redirector */ - public function enable2FA() + public function enable2FA(Request $request) { + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } + /** @var User $user */ $user = auth()->user(); $enabledMFA = null !== $user->mfa_secret; @@ -329,6 +344,12 @@ class ProfileController extends Controller */ public function newBackupCodes() { + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } + // generate recovery codes: $recovery = app(Recovery::class); $recoveryCodes = $recovery->lowercase() @@ -354,13 +375,10 @@ class ProfileController extends Controller */ public function postChangeEmail(EmailFormRequest $request, UserRepositoryInterface $repository) { - $loginProvider = config('firefly.login_provider'); - if ('eloquent' !== $loginProvider) { - // @codeCoverageIgnoreStart - $request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)])); + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); return redirect(route('profile.index')); - // @codeCoverageIgnoreEnd } /** @var User $user */ @@ -408,13 +426,10 @@ class ProfileController extends Controller */ public function postChangePassword(ProfileFormRequest $request, UserRepositoryInterface $repository) { - $loginProvider = config('firefly.login_provider'); - if ('eloquent' !== $loginProvider) { - // @codeCoverageIgnoreStart - $request->session()->flash('error', trans('firefly.login_provider_local_only', ['login_provider' => e($loginProvider)])); + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); return redirect(route('profile.index')); - // @codeCoverageIgnoreEnd } // the request has already validated both new passwords must be equal. @@ -446,6 +461,12 @@ class ProfileController extends Controller */ public function postCode(TokenFormRequest $request) { + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } + /** @var User $user */ $user = auth()->user(); /** @var UserRepositoryInterface $repository */ @@ -485,6 +506,12 @@ class ProfileController extends Controller */ public function postDeleteAccount(UserRepositoryInterface $repository, DeleteAccountFormRequest $request) { + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } + if (!Hash::check($request->get('password'), auth()->user()->password)) { session()->flash('error', (string) trans('firefly.invalid_password')); @@ -506,8 +533,14 @@ class ProfileController extends Controller * * @return RedirectResponse|Redirector */ - public function regenerate() + public function regenerate(Request $request) { + if ($this->externalIdentity) { + $request->session()->flash('error', trans('firefly.external_user_mgt_disabled')); + + return redirect(route('profile.index')); + } + /** @var User $user */ $user = auth()->user(); $token = $user->generateAccessToken(); @@ -530,11 +563,8 @@ class ProfileController extends Controller */ public function undoEmailChange(UserRepositoryInterface $repository, string $token, string $hash) { - $loginProvider = config('firefly.login_provider'); - if ('eloquent' !== $loginProvider) { - // @codeCoverageIgnoreStart - throw new FireflyException('Cannot confirm email change when authentication provider is not local.'); - // @codeCoverageIgnoreEnd + if ($this->externalIdentity) { + throw new FireflyException(trans('firefly.external_user_mgt_disabled')); } // find preference with this token value. diff --git a/app/Http/Controllers/Recurring/CreateController.php b/app/Http/Controllers/Recurring/CreateController.php index f2c45d1ac3..37d7325c40 100644 --- a/app/Http/Controllers/Recurring/CreateController.php +++ b/app/Http/Controllers/Recurring/CreateController.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Controllers\Recurring; use Carbon\Carbon; use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Requests\RecurrenceFormRequest; use FireflyIII\Models\RecurrenceRepetition; @@ -47,6 +48,8 @@ class CreateController extends Controller /** @var RecurringRepositoryInterface Recurring repository */ private $recurring; + private AttachmentHelperInterface $attachments; + /** * CreateController constructor. * @@ -63,8 +66,9 @@ class CreateController extends Controller app('view')->share('title', (string) trans('firefly.recurrences')); app('view')->share('subTitle', (string) trans('firefly.create_new_recurrence')); - $this->recurring = app(RecurringRepositoryInterface::class); - $this->budgets = app(BudgetRepositoryInterface::class); + $this->recurring = app(RecurringRepositoryInterface::class); + $this->budgets = app(BudgetRepositoryInterface::class); + $this->attachments = app(AttachmentHelperInterface::class); return $next($request); } @@ -140,6 +144,21 @@ class CreateController extends Controller $request->session()->flash('success', (string) trans('firefly.stored_new_recurrence', ['title' => $recurrence->title])); app('preferences')->mark(); + + // store attachment(s): + /** @var array $files */ + $files = $request->hasFile('attachments') ? $request->file('attachments') : null; + if (null !== $files && !auth()->user()->hasRole('demo')) { + $this->attachments->saveAttachmentsForModel($recurrence, $files); + } + if (null !== $files && auth()->user()->hasRole('demo')) { + session()->flash('info', (string) trans('firefly.no_att_demo_user')); + } + + if (count($this->attachments->getMessages()->get('attachments')) > 0) { + $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore + } + $redirect = redirect($this->getPreviousUri('recurring.create.uri')); if (1 === (int) $request->get('create_another')) { // set value so create routine will not overwrite URL: diff --git a/app/Http/Controllers/Recurring/EditController.php b/app/Http/Controllers/Recurring/EditController.php index fad9ef560c..22f5b49226 100644 --- a/app/Http/Controllers/Recurring/EditController.php +++ b/app/Http/Controllers/Recurring/EditController.php @@ -25,6 +25,7 @@ namespace FireflyIII\Http\Controllers\Recurring; use FireflyIII\Exceptions\FireflyException; +use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; use FireflyIII\Http\Controllers\Controller; use FireflyIII\Http\Requests\RecurrenceFormRequest; use FireflyIII\Models\Recurrence; @@ -48,7 +49,8 @@ class EditController extends Controller /** @var BudgetRepositoryInterface The budget repository */ private $budgets; /** @var RecurringRepositoryInterface Recurring repository */ - private $recurring; + private $recurring; + private AttachmentHelperInterface $attachments; /** * EditController constructor. @@ -66,9 +68,9 @@ class EditController extends Controller app('view')->share('title', (string) trans('firefly.recurrences')); app('view')->share('subTitle', (string) trans('firefly.recurrences')); - $this->recurring = app(RecurringRepositoryInterface::class); - $this->budgets = app(BudgetRepositoryInterface::class); - + $this->recurring = app(RecurringRepositoryInterface::class); + $this->budgets = app(BudgetRepositoryInterface::class); + $this->attachments = app(AttachmentHelperInterface::class); return $next($request); } ); @@ -159,6 +161,21 @@ class EditController extends Controller $this->recurring->update($recurrence, $data); $request->session()->flash('success', (string) trans('firefly.updated_recurrence', ['title' => $recurrence->title])); + + // store new attachment(s): + $files = $request->hasFile('attachments') ? $request->file('attachments') : null; + if (null !== $files && !auth()->user()->hasRole('demo')) { + $this->attachments->saveAttachmentsForModel($recurrence, $files); + } + if (null !== $files && auth()->user()->hasRole('demo')) { + session()->flash('info', (string) trans('firefly.no_att_demo_user')); + } + + if (count($this->attachments->getMessages()->get('attachments')) > 0) { + $request->session()->flash('info', $this->attachments->getMessages()->get('attachments')); // @codeCoverageIgnore + } + + app('preferences')->mark(); $redirect = redirect($this->getPreviousUri('recurrences.edit.uri')); if (1 === (int) $request->get('return_to_edit')) { diff --git a/app/Http/Controllers/Recurring/IndexController.php b/app/Http/Controllers/Recurring/IndexController.php index bcb6123a43..f7f682fb07 100644 --- a/app/Http/Controllers/Recurring/IndexController.php +++ b/app/Http/Controllers/Recurring/IndexController.php @@ -111,6 +111,8 @@ class IndexController extends Controller $array['first_date'] = new Carbon($array['first_date']); $array['repeat_until'] = null === $array['repeat_until'] ? null : new Carbon($array['repeat_until']); $array['latest_date'] = null === $array['latest_date'] ? null : new Carbon($array['latest_date']); + // lazy but OK + $array['attachments'] = $recurrence->attachments()->count(); // make carbon objects out of occurrences foreach ($array['repetitions'] as $repIndex => $repetition) { diff --git a/app/Http/Controllers/ReportController.php b/app/Http/Controllers/ReportController.php index f9b0cf5304..eec0c6fdda 100644 --- a/app/Http/Controllers/ReportController.php +++ b/app/Http/Controllers/ReportController.php @@ -263,7 +263,7 @@ class ReportController extends Controller public function index(AccountRepositoryInterface $repository) { /** @var Carbon $start */ - $start = clone session('first'); + $start = clone session('first', new Carbon); $months = $this->helper->listOfMonths($start); $customFiscalYear = app('preferences')->get('customFiscalYear', 0)->data; $accounts = $repository->getAccountsByType( diff --git a/app/Http/Controllers/Rule/SelectController.php b/app/Http/Controllers/Rule/SelectController.php index 807b6588fb..8833590a09 100644 --- a/app/Http/Controllers/Rule/SelectController.php +++ b/app/Http/Controllers/Rule/SelectController.php @@ -128,6 +128,10 @@ class SelectController extends Controller */ public function selectTransactions(Rule $rule) { + if(false===$rule->active) { + session()->flash('warning',trans('firefly.cannot_fire_inactive_rules')); + return redirect(route('rules.index')); + } // does the user have shared accounts? $first = session('first', Carbon::now()->subYear())->format('Y-m-d'); $today = Carbon::now()->format('Y-m-d'); diff --git a/app/Http/Requests/ObjectGroupFormRequest.php b/app/Http/Requests/ObjectGroupFormRequest.php new file mode 100644 index 0000000000..959bc1afaf --- /dev/null +++ b/app/Http/Requests/ObjectGroupFormRequest.php @@ -0,0 +1,75 @@ +. + */ +declare(strict_types=1); + +namespace FireflyIII\Http\Requests; + +use FireflyIII\Models\ObjectGroup; + +/** + * Class ObjectGroupFormRequest. + */ +class ObjectGroupFormRequest extends Request +{ + /** + * Verify the request. + * + * @return bool + */ + public function authorize(): bool + { + // Only allow logged in users + return auth()->check(); + } + + /** + * Returns the data required by the controller. + * + * @return array + */ + public function getObjectGroupData(): array + { + return [ + 'title' => $this->string('title'), + ]; + } + + /** + * Rules for this request. + * + * @return array + */ + public function rules(): array + { + /** @var ObjectGroup $piggy */ + $objectGroup = $this->route()->parameter('objectGroup'); + + $titleRule = 'required|between:1,255|uniqueObjectGroup'; + + if (null !== $objectGroup) { + $titleRule = sprintf('required|between:1,255|uniqueObjectGroup:%d', $objectGroup->id); + } + + return [ + 'title' => $titleRule, + ]; + } +} diff --git a/app/Http/Requests/PiggyBankFormRequest.php b/app/Http/Requests/PiggyBankFormRequest.php index d1eabc9754..afe336b96b 100644 --- a/app/Http/Requests/PiggyBankFormRequest.php +++ b/app/Http/Requests/PiggyBankFormRequest.php @@ -54,6 +54,7 @@ class PiggyBankFormRequest extends Request 'targetamount' => $this->string('targetamount'), 'targetdate' => $this->date('targetdate'), 'notes' => $this->nlString('notes'), + 'object_group' => $this->string('object_group'), ]; } diff --git a/app/Import/Converter/Amount.php b/app/Import/Converter/Amount.php deleted file mode 100644 index ee7630764d..0000000000 --- a/app/Import/Converter/Amount.php +++ /dev/null @@ -1,234 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Converter; - -use Log; - -/** - * Class Amount. - * - * @deprecated - * @codeCoverageIgnore - */ -class Amount implements ConverterInterface -{ - /** - * Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems. - * - Jamie Zawinski. - * - * @param $value - * - * @return string - */ - public function convert($value): string - { - if (null === $value) { - return '0'; - } - Log::debug(sprintf('Start with amount "%s"', $value)); - $original = $value; - $value = $this->stripAmount((string) $value); - $decimal = null; - - if ($this->decimalIsDot($value)) { - $decimal = '.'; - Log::debug(sprintf('Decimal character in "%s" seems to be a dot.', $value)); - } - - if ($this->decimalIsComma($value)) { - $decimal = ','; - Log::debug(sprintf('Decimal character in "%s" seems to be a comma.', $value)); - } - - // decimal character is null? find out if "0.1" or ".1" or "0,1" or ",1" - if ($this->alternativeDecimalSign($value)) { - $decimal = $this->getAlternativeDecimalSign($value); - } - - // decimal character still null? Search from the left for '.',',' or ' '. - if (null === $decimal) { - $decimal = $this->findFromLeft($value); - } - - // if decimal is dot, replace all comma's and spaces with nothing - if (null !== $decimal) { - $value = $this->replaceDecimal($decimal, $value); - Log::debug(sprintf('Converted amount from "%s" to "%s".', $original, $value)); - } - - if (null === $decimal) { - // replace all: - $search = ['.', ' ', ',']; - $value = str_replace($search, '', $value); - Log::debug(sprintf('No decimal character found. Converted amount from "%s" to "%s".', $original, $value)); - } - if (strpos($value, '.') === 0) { - $value = '0' . $value; - } - - if (is_numeric($value)) { - Log::debug(sprintf('Final NUMERIC value is: "%s"', $value)); - - return $value; - } - // @codeCoverageIgnoreStart - Log::debug(sprintf('Final value is: "%s"', $value)); - $formatted = sprintf('%01.12f', $value); - Log::debug(sprintf('Is formatted to : "%s"', $formatted)); - - return $formatted; - // @codeCoverageIgnoreEnd - } - - /** - * Check if the value has a dot or comma on an alternative place, - * catching strings like ",1" or ".5". - * - * @param string $value - * - * @return bool - */ - private function alternativeDecimalSign(string $value): bool - { - $length = strlen($value); - $altPosition = $length - 2; - - return $length > 1 && ('.' === $value[$altPosition] || ',' === $value[$altPosition]); - } - - /** - * Helper function to see if the decimal separator is a comma. - * - * @param string $value - * - * @return bool - */ - private function decimalIsComma(string $value): bool - { - $length = strlen($value); - $decimalPosition = $length - 3; - - return $length > 2 && ',' === $value[$decimalPosition]; - } - - /** - * Helper function to see if the decimal separator is a dot. - * - * @param string $value - * - * @return bool - */ - private function decimalIsDot(string $value): bool - { - $length = strlen($value); - $decimalPosition = $length - 3; - - return ($length > 2 && '.' === $value[$decimalPosition]) || ($length > 2 && strpos($value, '.') > $decimalPosition); - } - - /** - * Search from the left for decimal sign. - * - * @param string $value - * - * @return string - */ - private function findFromLeft(string $value): ?string - { - $decimal = null; - Log::debug('Decimal is still NULL, probably number with >2 decimals. Search for a dot.'); - $res = strrpos($value, '.'); - if (!(false === $res)) { - // blandly assume this is the one. - Log::debug(sprintf('Searched from the left for "." in amount "%s", assume this is the decimal sign.', $value)); - $decimal = '.'; - } - - return $decimal; - } - - /** - * Returns the alternative decimal point used, such as a dot or a comma, - * from strings like ",1" or "0.5". - * - * @param string $value - * - * @return string - */ - private function getAlternativeDecimalSign(string $value): string - { - $length = strlen($value); - $altPosition = $length - 2; - - return $value[$altPosition]; - - } - - /** - * Replaces other characters like thousand separators with nothing to make the decimal separator the only special - * character in the string. - * - * @param string $decimal - * @param string $value - * - * @return string - */ - private function replaceDecimal(string $decimal, string $value): string - { - $search = [',', ' ']; // default when decimal sign is a dot. - if (',' === $decimal) { - $search = ['.', ' ']; - } - $value = str_replace($search, '', $value); - - /** @noinspection CascadeStringReplacementInspection */ - $value = str_replace(',', '.', $value); - - return $value; - } - - /** - * Strip amount from weird characters. - * - * @param string $value - * - * @return string - */ - private function stripAmount(string $value): string - { - if (0 === strpos($value, '--')) { - $value = substr($value, 2); - } - // have to strip the € because apparantly the Postbank (DE) thinks "1.000,00 €" is a normal way to format a number. - $value = trim((string) str_replace(['€'], '', $value)); - $str = preg_replace('/[^\-\(\)\.\,0-9 ]/', '', $value); - $len = strlen($str); - if ('(' === $str[0] && ')' === $str[$len - 1]) { - $str = '-' . substr($str, 1, $len - 2); - } - - Log::debug(sprintf('Stripped "%s" away to "%s"', $value, $str)); - - return $str; - } -} diff --git a/app/Import/Converter/AmountCredit.php b/app/Import/Converter/AmountCredit.php deleted file mode 100644 index 3bfb2e6021..0000000000 --- a/app/Import/Converter/AmountCredit.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Converter; - -/** - * Class AmountCredit - * - * @deprecated - * @codeCoverageIgnore - */ -class AmountCredit implements ConverterInterface -{ - /** - * Convert an amount, always return positive. - * - * @param $value - * - * @return string - */ - public function convert($value): string - { - /** @var ConverterInterface $converter */ - $converter = app(Amount::class); - $result = $converter->convert($value); - $result = app('steam')->positive($result); - - return $result; - } -} diff --git a/app/Import/Converter/AmountDebit.php b/app/Import/Converter/AmountDebit.php deleted file mode 100644 index 4b96a34662..0000000000 --- a/app/Import/Converter/AmountDebit.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Converter; - -/** - * Class AmountDebit - * - * @deprecated - * @codeCoverageIgnore - */ -class AmountDebit implements ConverterInterface -{ - /** - * Convert amount, always return positive. - * - * @param $value - * - * @return string - */ - public function convert($value): string - { - /** @var ConverterInterface $converter */ - $converter = app(Amount::class); - $result = $converter->convert($value); - $result = app('steam')->positive($result); - $result = bcmul($result, '-1'); - - return $result; - } -} diff --git a/app/Import/Converter/AmountNegated.php b/app/Import/Converter/AmountNegated.php deleted file mode 100644 index 3bb2483e19..0000000000 --- a/app/Import/Converter/AmountNegated.php +++ /dev/null @@ -1,49 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Converter; - -/** - * Class AmountNegated - * - * @deprecated - * @codeCoverageIgnore - */ -class AmountNegated implements ConverterInterface -{ - /** - * Negate amount. - * - * @param $value - * - * @return string - */ - public function convert($value): string - { - /** @var ConverterInterface $converter */ - $converter = app(Amount::class); - $result = $converter->convert($value); - $result = bcmul($result, '-1'); - - return $result; - } -} diff --git a/app/Import/Converter/BankDebitCredit.php b/app/Import/Converter/BankDebitCredit.php deleted file mode 100644 index dcaa1d08f2..0000000000 --- a/app/Import/Converter/BankDebitCredit.php +++ /dev/null @@ -1,64 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\Converter; - - -use Log; - -/** - * - * Class BankDebitCredit - * - * @deprecated - * @codeCoverageIgnore - */ -class BankDebitCredit implements ConverterInterface -{ - - /** - * Convert a value. - * - * @param $value - * - * @return int - */ - public function convert($value): int - { - Log::debug('Going to convert ', ['value' => $value]); - $negative = [ - 'D', // Old style Rabobank (NL). Short for "Debit" - 'A', // New style Rabobank (NL). Short for "Af" - 'DR', // https://old.reddit.com/r/FireflyIII/comments/bn2edf/generic_debitcredit_indicator/ - 'Af', // ING (NL). - 'Debet', // Triodos (NL) - 'S', // "Soll", German term for debit - 'Debit', // Community America (US) - ]; - if (in_array(trim($value), $negative, true)) { - return -1; - } - - return 1; - } -} diff --git a/app/Import/Converter/ConverterInterface.php b/app/Import/Converter/ConverterInterface.php deleted file mode 100644 index bdf5176eb1..0000000000 --- a/app/Import/Converter/ConverterInterface.php +++ /dev/null @@ -1,42 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Converter; - -/** - * Interface ConverterInterface. - * - * @deprecated - * @codeCoverageIgnore - */ -interface ConverterInterface -{ - /** - * Convert a value. - * - * @param $value - * - * @return mixed - * - */ - public function convert($value); -} diff --git a/app/Import/JobConfiguration/BunqJobConfiguration.php b/app/Import/JobConfiguration/BunqJobConfiguration.php deleted file mode 100644 index c4c5f3644b..0000000000 --- a/app/Import/JobConfiguration/BunqJobConfiguration.php +++ /dev/null @@ -1,136 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\JobConfiguration\Bunq\BunqJobConfigurationInterface; -use FireflyIII\Support\Import\JobConfiguration\Bunq\ChooseAccountsHandler; -use FireflyIII\Support\Import\JobConfiguration\Bunq\NewBunqJobHandler; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class BunqJobConfiguration - * - * @deprecated - * @codeCoverageIgnore - */ -class BunqJobConfiguration implements JobConfigurationInterface -{ - /** @var BunqJobConfigurationInterface Bunq job interface */ - private $handler; - /** @var ImportJob The import job */ - private $importJob; - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * Returns true when the initial configuration for this job is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - return $this->handler->configurationComplete(); - } - - /** - * Store any data from the $data array into the job. Anything in the message bag will be flashed - * as an error to the user, regardless of its content. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - return $this->handler->configureJob($data); - } - - /** - * Return the data required for the next step in the job configuration. - * - * @return array - */ - public function getNextData(): array - { - return $this->handler->getNextData(); - } - - /** - * Returns the view of the next step in the job configuration. - * - * @return string - */ - public function getNextView(): string - { - return $this->handler->getNextView(); - } - - /** - * Set import job. - * - * @param ImportJob $importJob - * - * @throws FireflyException - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->handler = $this->getHandler(); - } - - /** - * Get correct handler. - * - * @throws FireflyException - * @return BunqJobConfigurationInterface - */ - private function getHandler(): BunqJobConfigurationInterface - { - Log::debug(sprintf('Now in BunqJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage)); - $handler = null; - switch ($this->importJob->stage) { - case 'new': - $handler = app(NewBunqJobHandler::class); - $handler->setImportJob($this->importJob); - break; - case 'choose-accounts': - /** @var ChooseAccountsHandler $handler */ - $handler = app(ChooseAccountsHandler::class); - $handler->setImportJob($this->importJob); - break; - default: - // @codeCoverageIgnoreStart - throw new FireflyException(sprintf('Firefly III cannot create a configuration handler for stage "%s"', $this->importJob->stage)); - // @codeCoverageIgnoreEnd - } - - return $handler; - } -} diff --git a/app/Import/JobConfiguration/FakeJobConfiguration.php b/app/Import/JobConfiguration/FakeJobConfiguration.php deleted file mode 100644 index 132de1ef00..0000000000 --- a/app/Import/JobConfiguration/FakeJobConfiguration.php +++ /dev/null @@ -1,169 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\MessageBag; - -/** - * Class FakeJobConfiguration - * - * @deprecated - * @codeCoverageIgnore - */ -class FakeJobConfiguration implements JobConfigurationInterface -{ - /** @var ImportJob The import job */ - private $importJob; - - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * Returns true when the initial configuration for this job is complete. - * configuration array of job must have two values: - * 'artist' must be 'david bowie', case insensitive - * 'song' must be 'golden years', case insensitive. - * if stage is not "new", then album must be 'station to station' - * - * @return bool - * - */ - public function configurationComplete(): bool - { - $config = $this->importJob->configuration; - if ('new' === $this->importJob->stage) { - return - isset($config['artist'], $config['song'], $config['apply-rules']) - && 'david bowie' === strtolower($config['artist']) - && 'golden years' === strtolower($config['song']); - } - - return isset($config['album']) && 'station to station' === strtolower($config['album']); - - - } - - /** - * Store any data from the $data array into the job. - * - * @param array $data - * - * @return MessageBag - * - */ - public function configureJob(array $data): MessageBag - { - $artist = strtolower($data['artist'] ?? ''); - $song = strtolower($data['song'] ?? ''); - $album = strtolower($data['album'] ?? ''); - $applyRules = isset($data['apply_rules']) ? 1 === (int) $data['apply_rules'] : null; - $configuration = $this->importJob->configuration; - if ('david bowie' === $artist) { - // store artist - $configuration['artist'] = $artist; - } - - if ('golden years' === $song) { - // store song - $configuration['song'] = $song; - } - - if ('station to station' === $album) { - // store album - $configuration['album'] = $album; - } - if (null !== $applyRules) { - $configuration['apply-rules'] = $applyRules; - } - - $this->repository->setConfiguration($this->importJob, $configuration); - $messages = new MessageBag(); - - if (3 !== count($configuration)) { - $messages->add('some_key', 'Ignore this error: ' . count($configuration)); - } - - return $messages; - } - - /** - * Return the data required for the next step in the job configuration. - * - * @codeCoverageIgnore - * @return array - */ - public function getNextData(): array - { - return [ - 'rulesOptions' => [ - 1 => (string) trans('firefly.yes'), - 0 => (string) trans('firefly.no'), - ], - ]; - } - - /** - * Returns the view of the next step in the job configuration. - * - * @return string - * - */ - public function getNextView(): string - { - // first configure artist: - $config = $this->importJob->configuration; - $artist = $config['artist'] ?? ''; - $song = $config['song'] ?? ''; - $album = $config['album'] ?? ''; - $applyRules = $config['apply-rules'] ?? null; - if (null === $applyRules) { - return 'import.fake.apply-rules'; - } - if ('david bowie' !== strtolower($artist)) { - return 'import.fake.enter-artist'; - } - if ('golden years' !== strtolower($song)) { - return 'import.fake.enter-song'; - } - if ('new' !== $this->importJob->stage && 'station to station' !== strtolower($album)) { - return 'import.fake.enter-album'; - } - - return 'impossible-view'; // @codeCoverageIgnore - } - - /** - * Set import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Import/JobConfiguration/FileJobConfiguration.php b/app/Import/JobConfiguration/FileJobConfiguration.php deleted file mode 100644 index 76cf4e2ec6..0000000000 --- a/app/Import/JobConfiguration/FileJobConfiguration.php +++ /dev/null @@ -1,161 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\JobConfiguration\File\ConfigureMappingHandler; -use FireflyIII\Support\Import\JobConfiguration\File\ConfigureRolesHandler; -use FireflyIII\Support\Import\JobConfiguration\File\ConfigureUploadHandler; -use FireflyIII\Support\Import\JobConfiguration\File\FileConfigurationInterface; -use FireflyIII\Support\Import\JobConfiguration\File\NewFileJobHandler; -use Illuminate\Support\MessageBag; - -/** - * Class FileJobConfiguration - * - * @deprecated - * @codeCoverageIgnore - */ -class FileJobConfiguration implements JobConfigurationInterface -{ - /** @var ImportJob The import job */ - private $importJob; - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * Returns true when the initial configuration for this job is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - return 'ready_to_run' === $this->importJob->stage; - } - - /** - * Store any data from the $data array into the job. Anything in the message bag will be flashed - * as an error to the user, regardless of its content. - * - * @param array $data - * - * @throws FireflyException - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - $configurator = $this->getConfigurationObject(); - $configurator->setImportJob($this->importJob); - - return $configurator->configureJob($data); - } - - /** - * Return the data required for the next step in the job configuration. - * - * @throws FireflyException - * @return array - */ - public function getNextData(): array - { - $configurator = $this->getConfigurationObject(); - $configurator->setImportJob($this->importJob); - - return $configurator->getNextData(); - } - - /** - * Returns the view of the next step in the job configuration. - * - * @throws FireflyException - * @return string - * - */ - public function getNextView(): string - { - switch ($this->importJob->stage) { - case 'new': - return 'import.file.new'; - case 'configure-upload': - return 'import.file.configure-upload'; - case 'roles': - return 'import.file.roles'; - case 'map': - return 'import.file.map'; - default: - // @codeCoverageIgnoreStart - throw new FireflyException( - sprintf('FileJobConfiguration::getNextView() cannot handle stage "%s"', $this->importJob->stage) - ); - // @codeCoverageIgnoreEnd - } - } - - /** - * Set import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - - /** - * Get the configuration handler for this specific stage. - * - * @throws FireflyException - * - * @return FileConfigurationInterface - */ - private function getConfigurationObject(): FileConfigurationInterface - { - $class = 'DoNotExist'; - switch ($this->importJob->stage) { - case 'new': // has nothing, no file upload or anything. - $class = NewFileJobHandler::class; - break; - case 'configure-upload': - $class = ConfigureUploadHandler::class; - break; - case 'roles': - $class = ConfigureRolesHandler::class; - break; - case 'map': - $class = ConfigureMappingHandler::class; - break; - } - if (!class_exists($class)) { - throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore - } - - return app($class); - } -} diff --git a/app/Import/JobConfiguration/FinTSConfigurationSteps.php b/app/Import/JobConfiguration/FinTSConfigurationSteps.php deleted file mode 100644 index 4a55c548b3..0000000000 --- a/app/Import/JobConfiguration/FinTSConfigurationSteps.php +++ /dev/null @@ -1,38 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - -/** - * - * Class FinTSConfigurationSteps - * - * @deprecated - * @codeCoverageIgnore - */ -abstract class FinTSConfigurationSteps -{ - public const NEW = 'new'; - public const CHOOSE_ACCOUNT = 'choose_account'; - public const GO_FOR_IMPORT = 'go-for-import'; -} diff --git a/app/Import/JobConfiguration/FinTSJobConfiguration.php b/app/Import/JobConfiguration/FinTSJobConfiguration.php deleted file mode 100644 index f7eb84bd95..0000000000 --- a/app/Import/JobConfiguration/FinTSJobConfiguration.php +++ /dev/null @@ -1,137 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Support\Import\JobConfiguration\FinTS\ChooseAccountHandler; -use FireflyIII\Support\Import\JobConfiguration\FinTS\FinTSConfigurationInterface; -use FireflyIII\Support\Import\JobConfiguration\FinTS\NewFinTSJobHandler; -use Illuminate\Support\MessageBag; - -/** - * - * Class FinTSJobConfiguration - * - * @deprecated - * @codeCoverageIgnore - */ -class FinTSJobConfiguration implements JobConfigurationInterface -{ - /** @var ImportJob */ - private $importJob; - - /** - * Returns true when the initial configuration for this job is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - return $this->importJob->stage === FinTSConfigurationSteps::GO_FOR_IMPORT; - } - - /** - * Store any data from the $data array into the job. Anything in the message bag will be flashed - * as an error to the user, regardless of its content. - * - * @param array $data - * - * @throws FireflyException - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - return $this->getConfigurationObject()->configureJob($data); - } - - /** - * Return the data required for the next step in the job configuration. - * - * @throws FireflyException - * @return array - */ - public function getNextData(): array - { - return $this->getConfigurationObject()->getNextData(); - } - - /** - * Returns the view of the next step in the job configuration. - * - * @throws FireflyException - * @return string - */ - public function getNextView(): string - { - switch ($this->importJob->stage) { - case FinTSConfigurationSteps::NEW: - case FinTSConfigurationSteps::CHOOSE_ACCOUNT: - return 'import.fints.' . $this->importJob->stage; - break; - default: - // @codeCoverageIgnoreStart - throw new FireflyException( - sprintf('FinTSJobConfiguration::getNextView() cannot handle stage "%s"', $this->importJob->stage) - ); - // @codeCoverageIgnoreEnd - } - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - } - - /** - * Get the configuration handler for this specific stage. - * - * @throws FireflyException - * @return FinTSConfigurationInterface - */ - private function getConfigurationObject(): FinTSConfigurationInterface - { - $class = 'DoNotExist'; - switch ($this->importJob->stage) { - case FinTSConfigurationSteps::NEW: - $class = NewFinTSJobHandler::class; - break; - case FinTSConfigurationSteps::CHOOSE_ACCOUNT: - $class = ChooseAccountHandler::class; - break; - } - if (!class_exists($class)) { - throw new FireflyException(sprintf('Class %s does not exist in getConfigurationClass().', $class)); // @codeCoverageIgnore - } - - $configurator = app($class); - $configurator->setImportJob($this->importJob); - - return $configurator; - } - - -} diff --git a/app/Import/JobConfiguration/JobConfigurationInterface.php b/app/Import/JobConfiguration/JobConfigurationInterface.php deleted file mode 100644 index 8d3343bb89..0000000000 --- a/app/Import/JobConfiguration/JobConfigurationInterface.php +++ /dev/null @@ -1,73 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; - -/** - * Interface JobConfigurationInterface. - * - * @deprecated - * @codeCoverageIgnore - */ -interface JobConfigurationInterface -{ - /** - * Returns true when the initial configuration for this job is complete. - * - * @return bool - */ - public function configurationComplete(): bool; - - /** - * Store any data from the $data array into the job. Anything in the message bag will be flashed - * as an error to the user, regardless of its content. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag; - - /** - * Return the data required for the next step in the job configuration. - * - * @return array - */ - public function getNextData(): array; - - /** - * Returns the view of the next step in the job configuration. - * - * @return string - */ - public function getNextView(): string; - - /** - * Set import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void; -} diff --git a/app/Import/JobConfiguration/SpectreJobConfiguration.php b/app/Import/JobConfiguration/SpectreJobConfiguration.php deleted file mode 100644 index 1bf3f12bdc..0000000000 --- a/app/Import/JobConfiguration/SpectreJobConfiguration.php +++ /dev/null @@ -1,156 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\JobConfiguration\Spectre\AuthenticatedHandler; -use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseAccountsHandler; -use FireflyIII\Support\Import\JobConfiguration\Spectre\ChooseLoginHandler; -use FireflyIII\Support\Import\JobConfiguration\Spectre\DoAuthenticateHandler; -use FireflyIII\Support\Import\JobConfiguration\Spectre\NewSpectreJobHandler; -use FireflyIII\Support\Import\JobConfiguration\Spectre\SpectreJobConfigurationInterface; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class SpectreJobConfiguration - * - * @deprecated - * @codeCoverageIgnore - */ -class SpectreJobConfiguration implements JobConfigurationInterface -{ - /** @var SpectreJobConfigurationInterface The job handler. */ - private $handler; - /** @var ImportJob The import job */ - private $importJob; - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * Returns true when the initial configuration for this job is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - return $this->handler->configurationComplete(); - } - - /** - * Store any data from the $data array into the job. Anything in the message bag will be flashed - * as an error to the user, regardless of its content. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - return $this->handler->configureJob($data); - } - - /** - * Return the data required for the next step in the job configuration. - * - * @return array - */ - public function getNextData(): array - { - return $this->handler->getNextData(); - } - - /** - * Returns the view of the next step in the job configuration. - * - * @return string - */ - public function getNextView(): string - { - return $this->handler->getNextView(); - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - * - * @throws FireflyException - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->handler = $this->getHandler(); - } - - /** - * Get correct handler. - * - * @throws FireflyException - * - * @return SpectreJobConfigurationInterface - */ - private function getHandler(): SpectreJobConfigurationInterface - { - Log::debug(sprintf('Now in SpectreJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage)); - $handler = null; - switch ($this->importJob->stage) { - case 'new': - /** @var NewSpectreJobHandler $handler */ - $handler = app(NewSpectreJobHandler::class); - $handler->setImportJob($this->importJob); - break; - case 'do-authenticate': - /** @var DoAuthenticateHandler $handler */ - $handler = app(DoAuthenticateHandler::class); - $handler->setImportJob($this->importJob); - break; - case 'choose-login': - /** @var ChooseLoginHandler $handler */ - $handler = app(ChooseLoginHandler::class); - $handler->setImportJob($this->importJob); - break; - case 'authenticated': - /** @var AuthenticatedHandler $handler */ - $handler = app(AuthenticatedHandler::class); - $handler->setImportJob($this->importJob); - break; - case 'choose-accounts': - /** @var ChooseAccountsHandler $handler */ - $handler = app(ChooseAccountsHandler::class); - $handler->setImportJob($this->importJob); - break; - default: - // @codeCoverageIgnoreStart - throw new FireflyException(sprintf('Firefly III cannot create a configuration handler for stage "%s"', $this->importJob->stage)); - // @codeCoverageIgnoreEnd - } - - return $handler; - } -} diff --git a/app/Import/JobConfiguration/YnabJobConfiguration.php b/app/Import/JobConfiguration/YnabJobConfiguration.php deleted file mode 100644 index 60ad0a52a9..0000000000 --- a/app/Import/JobConfiguration/YnabJobConfiguration.php +++ /dev/null @@ -1,143 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\JobConfiguration; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\JobConfiguration\Ynab\NewYnabJobHandler; -use FireflyIII\Support\Import\JobConfiguration\Ynab\SelectAccountsHandler; -use FireflyIII\Support\Import\JobConfiguration\Ynab\SelectBudgetHandler; -use FireflyIII\Support\Import\JobConfiguration\Ynab\YnabJobConfigurationInterface; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class YnabJobConfiguration - * - * @deprecated - * @codeCoverageIgnore - */ -class YnabJobConfiguration implements JobConfigurationInterface -{ - /** @var YnabJobConfigurationInterface The job handler. */ - private $handler; - /** @var ImportJob The import job */ - private $importJob; - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * Returns true when the initial configuration for this job is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - return $this->handler->configurationComplete(); - } - - /** - * Store any data from the $data array into the job. Anything in the message bag will be flashed - * as an error to the user, regardless of its content. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - return $this->handler->configureJob($data); - } - - /** - * Return the data required for the next step in the job configuration. - * - * @return array - */ - public function getNextData(): array - { - return $this->handler->getNextData(); - } - - /** - * Returns the view of the next step in the job configuration. - * - * @return string - */ - public function getNextView(): string - { - return $this->handler->getNextView(); - } - - /** - * Set import job. - * - * @param ImportJob $importJob - * - * @throws FireflyException - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->handler = $this->getHandler(); - } - - /** - * Get correct handler. - * - * @throws FireflyException - * - * @return YnabJobConfigurationInterface - */ - private function getHandler(): YnabJobConfigurationInterface - { - Log::debug(sprintf('Now in YnabJobConfiguration::getHandler() with stage "%s"', $this->importJob->stage)); - $handler = null; - switch ($this->importJob->stage) { - case 'new': - /** @var NewYnabJobHandler $handler */ - $handler = app(NewYnabJobHandler::class); - $handler->setImportJob($this->importJob); - break; - case 'select_budgets': - /** @var SelectBudgetHandler $handler */ - $handler = app(SelectBudgetHandler::class); - $handler->setImportJob($this->importJob); - break; - case 'select_accounts': - $handler = app(SelectAccountsHandler::class); - $handler->setImportJob($this->importJob); - break; - default: - // @codeCoverageIgnoreStart - throw new FireflyException(sprintf('Firefly III cannot create a YNAB configuration handler for stage "%s"', $this->importJob->stage)); - // @codeCoverageIgnoreEnd - } - - return $handler; - } -} diff --git a/app/Import/Mapper/AssetAccountIbans.php b/app/Import/Mapper/AssetAccountIbans.php deleted file mode 100644 index b754f7d75a..0000000000 --- a/app/Import/Mapper/AssetAccountIbans.php +++ /dev/null @@ -1,85 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; - -/** - * Class AssetAccounts. - * - * @deprecated - * @codeCoverageIgnore - */ -class AssetAccountIbans implements MapperInterface -{ - /** - * Get map of asset accounts. - * - * @return array - */ - public function getMap(): array - { - /** @var AccountRepositoryInterface $accountRepository */ - $accountRepository = app(AccountRepositoryInterface::class); - $set = $accountRepository->getAccountsByType( - [AccountType::DEFAULT, AccountType::ASSET, - AccountType::LOAN, AccountType::DEBT, - AccountType::CREDITCARD, AccountType::MORTGAGE, - ] - ); - $topList = []; - $list = []; - - /** @var Account $account */ - foreach ($set as $account) { - $iban = $account->iban ?? ''; - $accountId = (int) $account->id; - if ('' !== $iban) { - $name = $account->iban . ' (' . $account->name . ')'; - - // is a liability? - if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) { - $name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')'; - } - - $topList[$accountId] = $name; - } - if ('' === $iban) { - $name = $account->name; - // is a liability? - if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) { - $name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')'; - } - $list[$accountId] = $name; - } - } - /** @noinspection AdditionOperationOnArraysInspection */ - $list = $topList + $list; - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/AssetAccounts.php b/app/Import/Mapper/AssetAccounts.php deleted file mode 100644 index 0d303977c2..0000000000 --- a/app/Import/Mapper/AssetAccounts.php +++ /dev/null @@ -1,72 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; - -/** - * Class AssetAccounts. - * - * @deprecated - * @codeCoverageIgnore - */ -class AssetAccounts implements MapperInterface -{ - /** - * Get map of asset accounts. - * - * @return array - */ - public function getMap(): array - { - /** @var AccountRepositoryInterface $accountRepository */ - $accountRepository = app(AccountRepositoryInterface::class); - $set = $accountRepository->getAccountsByType( - [AccountType::DEFAULT, AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE,] - ); - $list = []; - - /** @var Account $account */ - foreach ($set as $account) { - $accountId = (int) $account->id; - $name = $account->name; - $iban = $account->iban ?? ''; - if ('' !== $iban) { - $name .= ' (' . $iban . ')'; - } - - // is a liability? - if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) { - $name = trans('import.import_liability_select') . ': ' . $name; - } - - $list[$accountId] = $name; - } - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/Bills.php b/app/Import/Mapper/Bills.php deleted file mode 100644 index 5ba45bd3da..0000000000 --- a/app/Import/Mapper/Bills.php +++ /dev/null @@ -1,58 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Bill; -use FireflyIII\Repositories\Bill\BillRepositoryInterface; - -/** - * Class Bills. - * - * @deprecated - * @codeCoverageIgnore - */ -class Bills implements MapperInterface -{ - /** - * Get map of bills. - * - * @return array - */ - public function getMap(): array - { - /** @var BillRepositoryInterface $repository */ - $repository = app(BillRepositoryInterface::class); - $result = $repository->getBills(); - $list = []; - - /** @var Bill $bill */ - foreach ($result as $bill) { - $billId = (int) $bill->id; - $list[$billId] = $bill->name; - } - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/Budgets.php b/app/Import/Mapper/Budgets.php deleted file mode 100644 index afe68219d6..0000000000 --- a/app/Import/Mapper/Budgets.php +++ /dev/null @@ -1,58 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Budget; -use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; - -/** - * Class Budgets. - * - * @deprecated - * @codeCoverageIgnore - */ -class Budgets implements MapperInterface -{ - /** - * Get map of budgets. - * - * @return array - */ - public function getMap(): array - { - /** @var BudgetRepositoryInterface $repository */ - $repository = app(BudgetRepositoryInterface::class); - $result = $repository->getActiveBudgets(); - $list = []; - - /** @var Budget $budget */ - foreach ($result as $budget) { - $budgetId = (int) $budget->id; - $list[$budgetId] = $budget->name; - } - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/Categories.php b/app/Import/Mapper/Categories.php deleted file mode 100644 index 2f398d6513..0000000000 --- a/app/Import/Mapper/Categories.php +++ /dev/null @@ -1,58 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Category; -use FireflyIII\Repositories\Category\CategoryRepositoryInterface; - -/** - * Class Categories. - * - * @deprecated - * @codeCoverageIgnore - */ -class Categories implements MapperInterface -{ - /** - * Get map of categories. - * - * @return array - */ - public function getMap(): array - { - /** @var CategoryRepositoryInterface $repository */ - $repository = app(CategoryRepositoryInterface::class); - $result = $repository->getCategories(); - $list = []; - - /** @var Category $category */ - foreach ($result as $category) { - $categoryId = (int) $category->id; - $list[$categoryId] = $category->name; - } - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/MapperInterface.php b/app/Import/Mapper/MapperInterface.php deleted file mode 100644 index be211d418b..0000000000 --- a/app/Import/Mapper/MapperInterface.php +++ /dev/null @@ -1,39 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -/** - * Interface MapperInterface. - * - * @deprecated - * @codeCoverageIgnore - */ -interface MapperInterface -{ - /** - * Get map of objects. - * - * @return array - */ - public function getMap(): array; -} diff --git a/app/Import/Mapper/OpposingAccountIbans.php b/app/Import/Mapper/OpposingAccountIbans.php deleted file mode 100644 index 117e5db0fd..0000000000 --- a/app/Import/Mapper/OpposingAccountIbans.php +++ /dev/null @@ -1,88 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; - -/** - * Class OpposingAccounts. - * - * @deprecated - * @codeCoverageIgnore - */ -class OpposingAccountIbans implements MapperInterface -{ - /** - * Get map of opposing accounts. - * - * @return array - */ - public function getMap(): array - { - /** @var AccountRepositoryInterface $accountRepository */ - $accountRepository = app(AccountRepositoryInterface::class); - $set = $accountRepository->getAccountsByType( - [ - AccountType::DEFAULT, AccountType::ASSET, - AccountType::EXPENSE, AccountType::BENEFICIARY, - AccountType::REVENUE, AccountType::LOAN, AccountType::DEBT, - AccountType::CREDITCARD, AccountType::MORTGAGE, - ] - ); - $topList = []; - $list = []; - - /** @var Account $account */ - foreach ($set as $account) { - $iban = $account->iban ?? ''; - $accountId = (int) $account->id; - if ('' !== $iban) { - $name = $account->iban . ' (' . $account->name . ')'; - - // is a liability? - if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) { - $name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')'; - } - - $topList[$accountId] = $name; - - } - if ('' === $iban) { - $name = $account->name; - // is a liability? - if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) { - $name = $name . ' (' . strtolower(trans('import.import_liability_select')) . ')'; - } - $list[$accountId] = $name; - } - } - /** @noinspection AdditionOperationOnArraysInspection */ - $list = $topList + $list; - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/OpposingAccounts.php b/app/Import/Mapper/OpposingAccounts.php deleted file mode 100644 index 99453cadeb..0000000000 --- a/app/Import/Mapper/OpposingAccounts.php +++ /dev/null @@ -1,76 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; - -/** - * Class OpposingAccounts. - * - * @deprecated - * @codeCoverageIgnore - * - */ -class OpposingAccounts implements MapperInterface -{ - /** - * Get map of opposing accounts. - * - * @return array - */ - public function getMap(): array - { - /** @var AccountRepositoryInterface $accountRepository */ - $accountRepository = app(AccountRepositoryInterface::class); - $set = $accountRepository->getAccountsByType( - [ - AccountType::DEFAULT, AccountType::ASSET, - AccountType::EXPENSE, AccountType::BENEFICIARY, - AccountType::REVENUE, AccountType::LOAN, AccountType::DEBT, - AccountType::CREDITCARD, AccountType::MORTGAGE, - ] - ); - $list = []; - - /** @var Account $account */ - foreach ($set as $account) { - $accountId = (int) $account->id; - $name = $account->name; - $iban = $account->iban ?? ''; - if ('' !== $iban) { - $name .= ' (' . $iban . ')'; - } - // is a liability? - if (in_array($account->accountType->type, [AccountType::LOAN, AccountType::DEBT, AccountType::CREDITCARD, AccountType::MORTGAGE], true)) { - $name = trans('import.import_liability_select') . ': ' . $name; - } - $list[$accountId] = $name; - } - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/Tags.php b/app/Import/Mapper/Tags.php deleted file mode 100644 index ea02687994..0000000000 --- a/app/Import/Mapper/Tags.php +++ /dev/null @@ -1,58 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Models\Tag; -use FireflyIII\Repositories\Tag\TagRepositoryInterface; - -/** - * Class Tags. - * - * @deprecated - * @codeCoverageIgnore - */ -class Tags implements MapperInterface -{ - /** - * Get map of tags. - * - * @return array - */ - public function getMap(): array - { - /** @var TagRepositoryInterface $repository */ - $repository = app(TagRepositoryInterface::class); - $result = $repository->get(); - $list = []; - - /** @var Tag $tag */ - foreach ($result as $tag) { - $tagId = (int) $tag->id; - $list[$tagId] = $tag->tag; - } - asort($list); - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/Mapper/TransactionCurrencies.php b/app/Import/Mapper/TransactionCurrencies.php deleted file mode 100644 index 613afcc54d..0000000000 --- a/app/Import/Mapper/TransactionCurrencies.php +++ /dev/null @@ -1,56 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Mapper; - -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; - -/** - * Class TransactionCurrencies. - * - * @deprecated - * @codeCoverageIgnore - */ -class TransactionCurrencies implements MapperInterface -{ - /** - * Get map of currencies. - * - * @return array - */ - public function getMap(): array - { - /** @var CurrencyRepositoryInterface $repository */ - $repository = app(CurrencyRepositoryInterface::class); - $currencies = $repository->get(); - $list = []; - foreach ($currencies as $currency) { - $currencyId = (int) $currency->id; - $list[$currencyId] = $currency->name . ' (' . $currency->code . ')'; - } - asort($list); - - $list = [0 => (string) trans('import.map_do_not_map')] + $list; - - return $list; - } -} diff --git a/app/Import/MapperPreProcess/PreProcessorInterface.php b/app/Import/MapperPreProcess/PreProcessorInterface.php deleted file mode 100644 index 9436db4078..0000000000 --- a/app/Import/MapperPreProcess/PreProcessorInterface.php +++ /dev/null @@ -1,41 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\MapperPreProcess; - -/** - * Interface PreProcessorInterface. - * - * @deprecated - * @codeCoverageIgnore - */ -interface PreProcessorInterface -{ - /** - * Run preprocessor. - * - * @param string $value - * - * @return array - */ - public function run(string $value): array; -} diff --git a/app/Import/MapperPreProcess/TagsComma.php b/app/Import/MapperPreProcess/TagsComma.php deleted file mode 100644 index 23427f02cc..0000000000 --- a/app/Import/MapperPreProcess/TagsComma.php +++ /dev/null @@ -1,48 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\MapperPreProcess; - -/** - * Class TagsComma. - * - * @deprecated - * @codeCoverageIgnore - */ -class TagsComma implements PreProcessorInterface -{ - /** - * Explode and filter list of comma separated tags. - * - * @param string $value - * - * @return array - */ - public function run(string $value): array - { - $set = explode(',', $value); - $set = array_map('trim', $set); - $set = array_filter($set, '\strlen'); - - return array_values($set); - } -} diff --git a/app/Import/MapperPreProcess/TagsSpace.php b/app/Import/MapperPreProcess/TagsSpace.php deleted file mode 100644 index bab216c2a1..0000000000 --- a/app/Import/MapperPreProcess/TagsSpace.php +++ /dev/null @@ -1,48 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\MapperPreProcess; - -/** - * Class TagsSpace. - * - * @deprecated - * @codeCoverageIgnore - */ -class TagsSpace implements PreProcessorInterface -{ - /** - * Explode and filter list of space separated tags. - * - * @param string $value - * - * @return array - */ - public function run(string $value): array - { - $set = explode(' ', $value); - $set = array_map('trim', $set); - $set = array_filter($set, '\strlen'); - - return array_values($set); - } -} diff --git a/app/Import/Prerequisites/BunqPrerequisites.php b/app/Import/Prerequisites/BunqPrerequisites.php deleted file mode 100644 index 664f3aba84..0000000000 --- a/app/Import/Prerequisites/BunqPrerequisites.php +++ /dev/null @@ -1,236 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Prerequisites; - -use bunq\Util\BunqEnumApiEnvironmentType; -use Exception; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Services\Bunq\ApiContext; -use FireflyIII\Services\IP\IPRetrievalInterface; -use FireflyIII\User; -use Illuminate\Support\MessageBag; -use Log; - -/** - * This class contains all the routines necessary to connect to Bunq. - * - * @deprecated - * @codeCoverageIgnore - */ -class BunqPrerequisites implements PrerequisitesInterface -{ - /** @var User The current user */ - private $user; - - /** - * BunqPrerequisites constructor. - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Returns view name that allows user to fill in prerequisites. - * - * @codeCoverageIgnore - * - * @return string - */ - public function getView(): string - { - return 'import.bunq.prerequisites'; - } - - /** - * Returns any values required for the prerequisites-view. - * - * @return array - */ - public function getViewParameters(): array - { - Log::debug('Now in BunqPrerequisites::getViewParameters()'); - $key = ''; - $externalIP = ''; - if ($this->hasApiKey()) { - $key = app('preferences')->getForUser($this->user, 'bunq_api_key', null)->data; - } - if ($this->hasExternalIP()) { - $externalIP = app('preferences')->getForUser($this->user, 'bunq_external_ip', null)->data; - } - if (!$this->hasExternalIP()) { - /** @var IPRetrievalInterface $service */ - $service = app(IPRetrievalInterface::class); - $externalIP = (string) $service->getIP(); - } - - return ['api_key' => $key, 'external_ip' => $externalIP]; - } - - /** - * Indicate if all prerequisites have been met. - * - * @return bool - */ - public function isComplete(): bool - { - return $this->hasApiKey() && $this->hasExternalIP() && $this->hasApiContext(); - } - - /** - * Set the user for this Prerequisites-routine. Class is expected to implement and save this. - * - * @param User $user - * - * @codeCoverageIgnore - */ - public function setUser(User $user): void - { - $this->user = $user; - } - - /** - * This method responds to the user's submission of an API key. Should do nothing but store the value. - * - * Errors must be returned in the message bag under the field name they are requested by. - * - * @param array $data - * - * @return MessageBag - * - */ - public function storePrerequisites(array $data): MessageBag - { - $apiKey = $data['api_key'] ?? ''; - $externalIP = $data['external_ip'] ?? ''; - Log::debug('Storing bunq API key'); - app('preferences')->setForUser($this->user, 'bunq_api_key', $apiKey); - app('preferences')->setForUser($this->user, 'bunq_external_ip', $externalIP); - $environment = $this->getBunqEnvironment(); - $deviceDescription = 'Firefly III v' . config('firefly.version'); - $permittedIps = [$externalIP]; - Log::debug(sprintf('Environment for bunq is %s', $environment->getChoiceString())); - - try { - /** @var ApiContext $object */ - $object = app(ApiContext::class); - $apiContext = $object->create($environment, $apiKey, $deviceDescription, $permittedIps); - } catch (FireflyException $e) { - $messages = new MessageBag(); - $messages->add('bunq_error', $e->getMessage()); - - return $messages; - } - // store context in JSON: - try { - $json = $apiContext->toJson(); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - $messages = new MessageBag(); - $messages->add('bunq_error', $e->getMessage()); - - return $messages; - } - // @codeCoverageIgnoreEnd - - // and store for user: - app('preferences')->setForUser($this->user, 'bunq_api_context', $json); - - return new MessageBag; - } - - /** - * Get correct bunq environment. - * - * @return BunqEnumApiEnvironmentType - * @codeCoverageIgnore - */ - private function getBunqEnvironment(): BunqEnumApiEnvironmentType - { - $env = config('firefly.bunq_use_sandbox'); - if (null === $env) { - return BunqEnumApiEnvironmentType::PRODUCTION(); - } - if (false === $env) { - return BunqEnumApiEnvironmentType::PRODUCTION(); - } - - return BunqEnumApiEnvironmentType::SANDBOX(); - } - - /** - * Check if we have API context. - * - * @return bool - */ - private function hasApiContext(): bool - { - $apiContext = app('preferences')->getForUser($this->user, 'bunq_api_context', null); - if (null === $apiContext) { - return false; - } - if ('' === (string) $apiContext->data) { - return false; - } - - return true; - } - - /** - * Check if we have the API key. - * - * @return bool - */ - private function hasApiKey(): bool - { - $apiKey = app('preferences')->getForUser($this->user, 'bunq_api_key', null); - if (null === $apiKey) { - return false; - } - if ('' === (string) $apiKey->data) { - return false; - } - - return true; - } - - /** - * Checks if we have an external IP. - * - * @return bool - */ - private function hasExternalIP(): bool - { - $externalIP = app('preferences')->getForUser($this->user, 'bunq_external_ip', null); - if (null === $externalIP) { - return false; - } - if ('' === (string) $externalIP->data) { - return false; - } - - return true; - } -} diff --git a/app/Import/Prerequisites/FakePrerequisites.php b/app/Import/Prerequisites/FakePrerequisites.php deleted file mode 100644 index 8f7ef94cb2..0000000000 --- a/app/Import/Prerequisites/FakePrerequisites.php +++ /dev/null @@ -1,146 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Prerequisites; - -use FireflyIII\User; -use Illuminate\Support\MessageBag; -use Log; -use function request; - -/** - * This class contains all the routines necessary for the fake import provider. - * - * Class FakePrerequisites - * - * @deprecated - * @codeCoverageIgnore - */ -class FakePrerequisites implements PrerequisitesInterface -{ - /** @var User The current user */ - private $user; - - /** - * FakePrerequisites constructor. - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Returns view name that allows user to fill in prerequisites. Currently asks for the API key. - * - * @codeCoverageIgnore - * @return string - */ - public function getView(): string - { - return 'import.fake.prerequisites'; - } - - /** - * Returns any values required for the prerequisites-view. - * - * @return array - */ - public function getViewParameters(): array - { - $apiKey = ''; - if ($this->hasApiKey()) { - $apiKey = app('preferences')->getForUser($this->user, 'fake_api_key', null)->data; - } - $oldKey = (string) request()->old('api_key'); - if ('' !== $oldKey) { - $apiKey = request()->old('api_key'); // @codeCoverageIgnore - } - - return ['api_key' => $apiKey]; - } - - /** - * Indicate if all prerequisites have been met. - * - * @return bool - */ - public function isComplete(): bool - { - return $this->hasApiKey(); - } - - /** - * Set the user for this Prerequisites-routine. Class is expected to implement and save this. - * - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - - } - - /** - * Store fake prerequisites. - * - * @param array $data - * - * @return MessageBag - */ - public function storePrerequisites(array $data): MessageBag - { - $apiKey = $data['api_key'] ?? ''; - $messageBag = new MessageBag(); - if (32 !== strlen($apiKey)) { - $messageBag->add('api_key', 'API key must be 32 chars.'); - - return $messageBag; - } - - app('preferences')->setForUser($this->user, 'fake_api_key', $apiKey); - - return $messageBag; - } - - /** - * Check if we have an API key. - * - * @return bool - */ - private function hasApiKey(): bool - { - $apiKey = app('preferences')->getForUser($this->user, 'fake_api_key', false); - if (null === $apiKey) { - return false; - } - if (null === $apiKey->data) { - return false; - } - if (32 === strlen((string) $apiKey->data)) { - return true; - } - - return false; - } -} diff --git a/app/Import/Prerequisites/FilePrerequisites.php b/app/Import/Prerequisites/FilePrerequisites.php deleted file mode 100644 index 8cfc105182..0000000000 --- a/app/Import/Prerequisites/FilePrerequisites.php +++ /dev/null @@ -1,102 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Prerequisites; - -use FireflyIII\User; -use Illuminate\Support\MessageBag; -use Log; - -/** - * - * This class contains all the routines necessary to import from a file. Hint: there are none. - * - * @deprecated - * @codeCoverageIgnore - */ -class FilePrerequisites implements PrerequisitesInterface -{ - - /** - * FilePrerequisites constructor. - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Returns view name that allows user to fill in prerequisites. - * - * @return string - */ - public function getView(): string - { - return ''; - } - - /** - * Returns any values required for the prerequisites-view. - * - * @return array - */ - public function getViewParameters(): array - { - return []; - } - - /** - * Indicate if all prerequisites have been met. - * - * @return bool - */ - public function isComplete(): bool - { - return true; - } - - /** - * Set the user for this Prerequisites-routine. Class is expected to implement and save this. - * - * @param User $user - */ - public function setUser(User $user): void - { - - } - - /** - * This method responds to the user's submission of an API key. Should do nothing but store the value. - * - * Errors must be returned in the message bag under the field name they are requested by. - * - * @param array $data - * - * @return MessageBag - */ - public function storePrerequisites(array $data): MessageBag - { - return new MessageBag; - } -} diff --git a/app/Import/Prerequisites/PrerequisitesInterface.php b/app/Import/Prerequisites/PrerequisitesInterface.php deleted file mode 100644 index 4ac3992b6e..0000000000 --- a/app/Import/Prerequisites/PrerequisitesInterface.php +++ /dev/null @@ -1,74 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Prerequisites; - -use FireflyIII\User; -use Illuminate\Support\MessageBag; - -/** - * Interface PrerequisitesInterface - * - * @deprecated - * @codeCoverageIgnore - */ -interface PrerequisitesInterface -{ - /** - * Returns view name that allows user to fill in prerequisites. - * - * @return string - */ - public function getView(): string; - - /** - * Returns any values required for the prerequisites-view. - * - * @return array - */ - public function getViewParameters(): array; - - /** - * Indicate if all prerequisites have been met. - * - * @return bool - */ - public function isComplete(): bool; - - /** - * Set the user for this Prerequisites-routine. Class is expected to implement and save this. - * - * @param User $user - */ - public function setUser(User $user): void; - - /** - * This method responds to the user's submission of an API key. Should do nothing but store the value. - * - * Errors must be returned in the message bag under the field name they are requested by. - * - * @param array $data - * - * @return MessageBag - */ - public function storePrerequisites(array $data): MessageBag; -} diff --git a/app/Import/Prerequisites/SpectrePrerequisites.php b/app/Import/Prerequisites/SpectrePrerequisites.php deleted file mode 100644 index 2746c870bf..0000000000 --- a/app/Import/Prerequisites/SpectrePrerequisites.php +++ /dev/null @@ -1,206 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Prerequisites; - -use FireflyIII\Models\Preference; -use FireflyIII\User; -use Illuminate\Support\MessageBag; -use Log; - -/** - * This class contains all the routines necessary to connect to Spectre. - * - * @deprecated - * @codeCoverageIgnore - */ -class SpectrePrerequisites implements PrerequisitesInterface -{ - /** @var User The current user */ - private $user; - - /** - * SpectrePrerequisites constructor. - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Returns view name that allows user to fill in prerequisites. - * - * @return string - */ - public function getView(): string - { - return 'import.spectre.prerequisites'; - } - - /** - * Returns any values required for the prerequisites-view. - * - * @return array - */ - public function getViewParameters(): array - { - /** @var Preference $appIdPreference */ - $appIdPreference = app('preferences')->getForUser($this->user, 'spectre_app_id', null); - $appId = null === $appIdPreference ? '' : $appIdPreference->data; - /** @var Preference $secretPreference */ - $secretPreference = app('preferences')->getForUser($this->user, 'spectre_secret', null); - $secret = null === $secretPreference ? '' : $secretPreference->data; - $publicKey = $this->getPublicKey(); - - return [ - 'app_id' => $appId, - 'secret' => $secret, - 'public_key' => $publicKey, - ]; - } - - /** - * Indicate if all prerequisites have been met. - * - * @return bool - */ - public function isComplete(): bool - { - return $this->hasAppId() && $this->hasSecret(); - } - - /** - * Set the user for this Prerequisites-routine. Class is expected to implement and save this. - * - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - } - - /** - * This method responds to the user's submission of an API key. Should do nothing but store the value. - * - * Errors must be returned in the message bag under the field name they are requested by. - * - * @param array $data - * - * @return MessageBag - */ - public function storePrerequisites(array $data): MessageBag - { - Log::debug('Storing Spectre API keys..'); - app('preferences')->setForUser($this->user, 'spectre_app_id', $data['app_id'] ?? null); - app('preferences')->setForUser($this->user, 'spectre_secret', $data['secret'] ?? null); - Log::debug('Done!'); - - return new MessageBag; - } - - /** - * This method creates a new public/private keypair for the user. This isn't really secure, since the key is generated on the fly with - * no regards for HSM's, smart cards or other things. It would require some low level programming to get this right. But the private key - * is stored encrypted in the database so it's something. - */ - private function createKeyPair(): void - { - Log::debug('Generate new Spectre key pair for user.'); - $keyConfig = [ - 'digest_alg' => 'sha512', - 'private_key_bits' => 2048, - 'private_key_type' => OPENSSL_KEYTYPE_RSA, - ]; - // Create the private and public key - $res = openssl_pkey_new($keyConfig); - - // Extract the private key from $res to $privKey - $privKey = ''; - openssl_pkey_export($res, $privKey); - - // Extract the public key from $res to $pubKey - $pubKey = openssl_pkey_get_details($res); - - app('preferences')->setForUser($this->user, 'spectre_private_key', $privKey); - app('preferences')->setForUser($this->user, 'spectre_public_key', $pubKey['key']); - Log::debug('Created key pair'); - - } - - /** - * Get a public key from the users preferences. - * - * @return string - */ - private function getPublicKey(): string - { - Log::debug('get public key'); - $preference = app('preferences')->getForUser($this->user, 'spectre_public_key', null); - if (null === $preference) { - Log::debug('public key is null'); - // create key pair - $this->createKeyPair(); - } - $preference = app('preferences')->getForUser($this->user, 'spectre_public_key', null); - Log::debug('Return public key for user'); - - return $preference->data; - } - - /** - * Check if we have the App ID. - * - * @return bool - */ - private function hasAppId(): bool - { - $appId = app('preferences')->getForUser($this->user, 'spectre_app_id', null); - if (null === $appId) { - return false; - } - if ('' === (string) $appId->data) { - return false; - } - - return true; - } - - /** - * Check if we have the secret. - * - * @return bool - */ - private function hasSecret(): bool - { - $secret = app('preferences')->getForUser($this->user, 'spectre_secret', null); - if (null === $secret) { - return false; - } - if ('' === (string) $secret->data) { - return false; - } - - return true; - } -} diff --git a/app/Import/Prerequisites/YnabPrerequisites.php b/app/Import/Prerequisites/YnabPrerequisites.php deleted file mode 100644 index 234ea3201f..0000000000 --- a/app/Import/Prerequisites/YnabPrerequisites.php +++ /dev/null @@ -1,159 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\Prerequisites; - -use FireflyIII\User; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class YnabPrerequisites - * - * @deprecated - * @codeCoverageIgnore - */ -class YnabPrerequisites implements PrerequisitesInterface -{ - /** @var User The current user */ - private $user; - - /** - * YnabPrerequisites constructor. - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Returns view name that allows user to fill in prerequisites. - * - * @return string - */ - public function getView(): string - { - return 'import.ynab.prerequisites'; - } - - /** - * Returns any values required for the prerequisites-view. - * - * @return array - */ - public function getViewParameters(): array - { - Log::debug('Now in YnabPrerequisites::getViewParameters()'); - $clientId = ''; - $clientSecret = ''; - if ($this->hasClientId()) { - $clientId = app('preferences')->getForUser($this->user, 'ynab_client_id', null)->data; - } - if ($this->hasClientSecret()) { - $clientSecret = app('preferences')->getForUser($this->user, 'ynab_client_secret', null)->data; - } - - $callBackUri = route('import.callback.ynab'); - $isHttps = 0 === strpos($callBackUri, 'https://'); - - return ['client_id' => $clientId, 'client_secret' => $clientSecret, 'callback_uri' => $callBackUri, 'is_https' => $isHttps]; - } - - /** - * Indicate if all prerequisites have been met. - * - * @return bool - */ - public function isComplete(): bool - { - return $this->hasClientId() && $this->hasClientSecret(); - } - - /** - * Set the user for this Prerequisites-routine. Class is expected to implement and save this. - * - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - } - - /** - * This method responds to the user's submission of an API key. Should do nothing but store the value. - * - * Errors must be returned in the message bag under the field name they are requested by. - * - * @param array $data - * - * @return MessageBag - */ - public function storePrerequisites(array $data): MessageBag - { - $clientId = $data['client_id'] ?? ''; - $clientSecret = $data['client_secret'] ?? ''; - Log::debug('Storing YNAB client data'); - app('preferences')->setForUser($this->user, 'ynab_client_id', $clientId); - app('preferences')->setForUser($this->user, 'ynab_client_secret', $clientSecret); - - return new MessageBag; - } - - /** - * Check if we have the client ID. - * - * @return bool - */ - private function hasClientId(): bool - { - $clientId = app('preferences')->getForUser($this->user, 'ynab_client_id', null); - if (null === $clientId) { - return false; - } - if ('' === (string) $clientId->data) { - return false; - } - - return true; - } - - /** - * Check if we have the client secret - * - * @return bool - */ - private function hasClientSecret(): bool - { - $clientSecret = app('preferences')->getForUser($this->user, 'ynab_client_secret', null); - if (null === $clientSecret) { - return false; - } - if ('' === (string) $clientSecret->data) { - return false; - } - - return true; - } -} diff --git a/app/Import/Routine/BunqRoutine.php b/app/Import/Routine/BunqRoutine.php deleted file mode 100644 index c70e425936..0000000000 --- a/app/Import/Routine/BunqRoutine.php +++ /dev/null @@ -1,118 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\Routine; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Routine\Bunq\StageImportDataHandler; -use FireflyIII\Support\Import\Routine\Bunq\StageNewHandler; -use Log; - -/** - * Class BunqRoutine - * - * @deprecated - * @codeCoverageIgnore - */ -class BunqRoutine implements RoutineInterface -{ - /** @var ImportJob The import job */ - private $importJob; - - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * At the end of each run(), the import routine must set the job to the expected status. - * - * The final status of the routine must be "provider_finished". - * - * @throws FireflyException - */ - public function run(): void - { - Log::info(sprintf('Now in BunqRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage)); - $valid = ['ready_to_run']; // should be only ready_to_run - if (in_array($this->importJob->status, $valid, true)) { - switch ($this->importJob->stage) { - default: - throw new FireflyException(sprintf('BunqRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore - case 'new': - // list all of the users accounts. - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageNewHandler $handler */ - $handler = app(StageNewHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - // make user choose accounts to import from. - $this->repository->setStage($this->importJob, 'choose-accounts'); - $this->repository->setStatus($this->importJob, 'need_job_config'); - - return; - case 'go-for-import': - // list all of the users accounts. - $this->repository->setStatus($this->importJob, 'running'); - - /** @var StageImportDataHandler $handler */ - $handler = app(StageImportDataHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - $transactions = $handler->getTransactions(); - // could be that more transactions will arrive in a second run. - if (true === $handler->isStillRunning()) { - Log::debug('Handler indicates that it is still working.'); - $this->repository->setStatus($this->importJob, 'ready_to_run'); - $this->repository->setStage($this->importJob, 'go-for-import'); - } - $this->repository->appendTransactions($this->importJob, $transactions); - if (false === $handler->isStillRunning()) { - Log::info('Handler indicates that its done!'); - $this->repository->setStatus($this->importJob, 'provider_finished'); - $this->repository->setStage($this->importJob, 'final'); - } - - - return; - } - } - throw new FireflyException(sprintf('bunq import routine cannot handle status "%s"', $this->importJob->status)); // @codeCoverageIgnore - } - - - /** - * Set the import job. - * - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - -} diff --git a/app/Import/Routine/FakeRoutine.php b/app/Import/Routine/FakeRoutine.php deleted file mode 100644 index 8e81b8fe4a..0000000000 --- a/app/Import/Routine/FakeRoutine.php +++ /dev/null @@ -1,111 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\Routine; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Routine\Fake\StageAhoyHandler; -use FireflyIII\Support\Import\Routine\Fake\StageFinalHandler; -use FireflyIII\Support\Import\Routine\Fake\StageNewHandler; -use Log; - -/** - * Class FakeRoutine - * - * @deprecated - * @codeCoverageIgnore - */ -class FakeRoutine implements RoutineInterface -{ - /** @var ImportJob The import job */ - private $importJob; - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * Fake import routine has three stages: - * - * "new": will quietly log gibberish for 15 seconds, then switch to stage "ahoy". - * will also set status to "ready_to_run" so it will arrive here again. - * "ahoy": will log some nonsense and then drop job into status:"need_job_config" to force it back to the job config routine. - * "final": will do some logging, sleep for 10 seconds and then finish. Generates 5 random transactions. - * - * @throws FireflyException - * - * @return void - */ - public function run(): void - { - Log::debug(sprintf('Now in run() for fake routine with status: %s', $this->importJob->status)); - if ('ready_to_run' !== $this->importJob->status) { - throw new FireflyException(sprintf('Fake job should have status "ready_to_run", not "%s"', $this->importJob->status)); // @codeCoverageIgnore - } - - switch ($this->importJob->stage) { - default: - throw new FireflyException(sprintf('Fake routine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore - case 'new': - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageNewHandler $handler */ - $handler = app(StageNewHandler::class); - $handler->run(); - $this->repository->setStage($this->importJob, 'ahoy'); - // set job finished this step: - $this->repository->setStatus($this->importJob, 'ready_to_run'); - - return; - case 'ahoy': - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageAhoyHandler $handler */ - $handler = app(StageAhoyHandler::class); - $handler->run(); - $this->repository->setStatus($this->importJob, 'need_job_config'); - $this->repository->setStage($this->importJob, 'final'); - break; - case 'final': - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageFinalHandler $handler */ - $handler = app(StageFinalHandler::class); - $handler->setImportJob($this->importJob); - $transactions = $handler->getTransactions(); - $this->repository->setStatus($this->importJob, 'provider_finished'); - $this->repository->setStage($this->importJob, 'final'); - $this->repository->setTransactions($this->importJob, $transactions); - } - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - * - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Import/Routine/FileRoutine.php b/app/Import/Routine/FileRoutine.php deleted file mode 100644 index c54d71b911..0000000000 --- a/app/Import/Routine/FileRoutine.php +++ /dev/null @@ -1,99 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Routine; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Routine\File\FileProcessorInterface; -use Log; - -/** - * Class FileRoutine - * - * @deprecated - * @codeCoverageIgnore - */ -class FileRoutine implements RoutineInterface -{ - /** @var ImportJob The import job */ - private $importJob; - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * At the end of each run(), the import routine must set the job to the expected status. - * - * The final status of the routine must be "provider_finished". - * - * @throws FireflyException - */ - public function run(): void - { - Log::debug(sprintf('Now in run() for file routine with status: %s', $this->importJob->status)); - if ('ready_to_run' === $this->importJob->status) { - $this->repository->setStatus($this->importJob, 'running'); - // get processor, depending on file type - // is just CSV for now. - $processor = $this->getProcessor(); - $processor->setImportJob($this->importJob); - $transactions = $processor->run(); - - $this->repository->setStatus($this->importJob, 'provider_finished'); - $this->repository->setStage($this->importJob, 'final'); - $this->repository->setTransactions($this->importJob, $transactions); - - return; - } - throw new FireflyException(sprintf('Import routine cannot handle status "%s"', $this->importJob->status)); // @codeCoverageIgnore - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - - /** - * Return the appropriate file routine handler for - * the file type of the job. - * - * @return FileProcessorInterface - */ - private function getProcessor(): FileProcessorInterface - { - $config = $this->repository->getConfiguration($this->importJob); - $type = $config['file-type'] ?? 'csv'; - $class = config(sprintf('import.options.file.processors.%s', $type)); - - return app($class); - } -} diff --git a/app/Import/Routine/FinTSRoutine.php b/app/Import/Routine/FinTSRoutine.php deleted file mode 100644 index 6cb2f72f11..0000000000 --- a/app/Import/Routine/FinTSRoutine.php +++ /dev/null @@ -1,89 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Routine; - - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Import\JobConfiguration\FinTSConfigurationSteps; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Routine\FinTS\StageImportDataHandler; -use Illuminate\Support\Facades\Log; - -/** - * - * Class FinTSRoutine - * - * @deprecated - * @codeCoverageIgnore - */ -class FinTSRoutine implements RoutineInterface -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * At the end of each run(), the import routine must set the job to the expected status. - * - * The final status of the routine must be "provider_finished". - * - * @throws FireflyException - */ - public function run(): void - { - Log::debug(sprintf('Now in FinTSRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage)); - $valid = ['ready_to_run']; // should be only ready_to_run - if (in_array($this->importJob->status, $valid, true)) { - switch ($this->importJob->stage) { - default: - throw new FireflyException(sprintf('FinTSRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore - case FinTSConfigurationSteps::GO_FOR_IMPORT: - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageImportDataHandler $handler */ - $handler = app(StageImportDataHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - $transactions = $handler->getTransactions(); - - $this->repository->setTransactions($this->importJob, $transactions); - $this->repository->setStatus($this->importJob, 'provider_finished'); - $this->repository->setStage($this->importJob, 'final'); - } - } - } - - /** - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - -} diff --git a/app/Import/Routine/RoutineInterface.php b/app/Import/Routine/RoutineInterface.php deleted file mode 100644 index 8d02979e06..0000000000 --- a/app/Import/Routine/RoutineInterface.php +++ /dev/null @@ -1,53 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Routine; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; - -/** - * Interface RoutineInterface - * - * @deprecated - * @codeCoverageIgnore - */ -interface RoutineInterface -{ - /** - * At the end of each run(), the import routine must set the job to the expected status. - * - * The final status of the routine must be "provider_finished". - * - * @throws FireflyException - */ - public function run(): void; - - /** - * Set the import job. - * - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void; -} diff --git a/app/Import/Routine/SpectreRoutine.php b/app/Import/Routine/SpectreRoutine.php deleted file mode 100644 index 984ef19c68..0000000000 --- a/app/Import/Routine/SpectreRoutine.php +++ /dev/null @@ -1,128 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Routine; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Routine\Spectre\StageAuthenticatedHandler; -use FireflyIII\Support\Import\Routine\Spectre\StageImportDataHandler; -use FireflyIII\Support\Import\Routine\Spectre\StageNewHandler; -use Log; - -/** - * Class SpectreRoutine - * - * @deprecated - * @codeCoverageIgnore - */ -class SpectreRoutine implements RoutineInterface -{ - - /** @var ImportJob The import job */ - private $importJob; - - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * At the end of each run(), the import routine must set the job to the expected status. - * - * The final status of the routine must be "provider_finished". - * - * @throws FireflyException - * - */ - public function run(): void - { - Log::debug(sprintf('Now in SpectreRoutine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage)); - $valid = ['ready_to_run']; // should be only ready_to_run - if (in_array($this->importJob->status, $valid, true)) { - switch ($this->importJob->stage) { - default: - throw new FireflyException(sprintf('SpectreRoutine cannot handle stage "%s".', $this->importJob->stage)); // @codeCoverageIgnore - case 'new': - // list all of the users logins. - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageNewHandler $handler */ - $handler = app(StageNewHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - - // if count logins is zero, go to authenticate stage - if (0 === $handler->getCountLogins()) { - $this->repository->setStage($this->importJob, 'do-authenticate'); - $this->repository->setStatus($this->importJob, 'ready_to_run'); - - return; - } - // or return to config to select login. - $this->repository->setStage($this->importJob, 'choose-login'); - $this->repository->setStatus($this->importJob, 'need_job_config'); - break; - case 'do-authenticate': - // set job to require config. - $this->repository->setStatus($this->importJob, 'need_job_config'); - - return; - case 'authenticated': - $this->repository->setStatus($this->importJob, 'running'); - // get accounts from login, store in job. - /** @var StageAuthenticatedHandler $handler */ - $handler = app(StageAuthenticatedHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - - // return to config to select account(s). - $this->repository->setStage($this->importJob, 'choose-accounts'); - $this->repository->setStatus($this->importJob, 'need_job_config'); - break; - case 'go-for-import': - // user has chosen account mapping. Should now be ready to import data. - $this->repository->setStatus($this->importJob, 'running'); - $this->repository->setStage($this->importJob, 'do_import'); - /** @var StageImportDataHandler $handler */ - $handler = app(StageImportDataHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - $this->repository->setStatus($this->importJob, 'provider_finished'); - $this->repository->setStage($this->importJob, 'final'); - } - } - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - -} diff --git a/app/Import/Routine/YnabRoutine.php b/app/Import/Routine/YnabRoutine.php deleted file mode 100644 index 5b2cd57197..0000000000 --- a/app/Import/Routine/YnabRoutine.php +++ /dev/null @@ -1,146 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\Routine; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Routine\Ynab\GetAccountsHandler; -use FireflyIII\Support\Import\Routine\Ynab\ImportDataHandler; -use FireflyIII\Support\Import\Routine\Ynab\StageGetAccessHandler; -use FireflyIII\Support\Import\Routine\Ynab\StageGetBudgetsHandler; -use Log; - -/** - * Class YnabRoutine - * - * @deprecated - * @codeCoverageIgnore - */ -class YnabRoutine implements RoutineInterface -{ - /** @var ImportJob The import job */ - private $importJob; - - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - - /** - * At the end of each run(), the import routine must set the job to the expected status. - * - * The final status of the routine must be "provider_finished". - * - * @throws FireflyException - */ - public function run(): void - { - Log::debug(sprintf('Now in YNAB routine::run() with status "%s" and stage "%s".', $this->importJob->status, $this->importJob->stage)); - $valid = ['ready_to_run']; // should be only ready_to_run - if (in_array($this->importJob->status, $valid, true)) { - - // get access token from YNAB - if ('get_access_token' === $this->importJob->stage) { - // list all of the users accounts. - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageGetAccessHandler $handler */ - $handler = app(StageGetAccessHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - - // back to correct stage: - $this->repository->setStatus($this->importJob, 'ready_to_run'); - $this->repository->setStage($this->importJob, 'get_budgets'); - - return; - } - if ('get_budgets' === $this->importJob->stage) { - $this->repository->setStatus($this->importJob, 'running'); - /** @var StageGetBudgetsHandler $handler */ - $handler = app(StageGetBudgetsHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - - // count budgets in job, to determine next step. - $configuration = $this->repository->getConfiguration($this->importJob); - $budgets = $configuration['budgets'] ?? []; - - // if more than 1 budget, select budget first. - if (count($budgets) > 1) { - $this->repository->setStage($this->importJob, 'select_budgets'); - $this->repository->setStatus($this->importJob, 'need_job_config'); - - return; - } - - if (1 === count($budgets)) { - $this->repository->setStatus($this->importJob, 'ready_to_run'); - $this->repository->setStage($this->importJob, 'get_accounts'); - } - - return; - } - if ('get_accounts' === $this->importJob->stage) { - $this->repository->setStatus($this->importJob, 'running'); - - /** @var GetAccountsHandler $handler */ - $handler = app(GetAccountsHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - - $this->repository->setStage($this->importJob, 'select_accounts'); - $this->repository->setStatus($this->importJob, 'need_job_config'); - - return; - } - if ('go-for-import' === $this->importJob->stage) { - $this->repository->setStatus($this->importJob, 'running'); - $this->repository->setStage($this->importJob, 'do_import'); - /** @var ImportDataHandler $handler */ - $handler = app(ImportDataHandler::class); - $handler->setImportJob($this->importJob); - $handler->run(); - $this->repository->setStatus($this->importJob, 'provider_finished'); - $this->repository->setStage($this->importJob, 'final'); - - return; - } - - throw new FireflyException(sprintf('YNAB import routine cannot handle stage "%s"', $this->importJob->stage)); - } - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Import/Specifics/AbnAmroDescription.php b/app/Import/Specifics/AbnAmroDescription.php deleted file mode 100644 index d15d42e35d..0000000000 --- a/app/Import/Specifics/AbnAmroDescription.php +++ /dev/null @@ -1,243 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Specifics; - -/** - * Class AbnAmroDescription. - * - * @deprecated - * @codeCoverageIgnore - * - * Parses the description from txt files for ABN AMRO bank accounts. - * - * Based on the logic as described in the following Gist: - * https://gist.github.com/vDorst/68d555a6a90f62fec004 - */ -class AbnAmroDescription implements SpecificInterface -{ - /** @var array The current row. */ - public $row; - - /** - * Description of this specific fix. - * - * @return string - * @codeCoverageIgnore - */ - public static function getDescription(): string - { - return 'import.specific_abn_descr'; - } - - /** - * Name of specific fix. - * - * @return string - * @codeCoverageIgnore - */ - public static function getName(): string - { - return 'import.specific_abn_name'; - } - - /** - * Run the fix. - * - * @param array $row - * - * @return array - * - */ - public function run(array $row): array - { - $this->row = array_values($row); - - if (!isset($row[7])) { - return $row; - } - - // Try to parse the description in known formats. - $parsed = $this->parseSepaDescription() || $this->parseTRTPDescription() || $this->parseGEABEADescription() || $this->parseABNAMRODescription(); - - // If the description could not be parsed, specify an unknown opposing - // account, as an opposing account is required - if (!$parsed) { - $this->row[8] = (string) trans('firefly.unknown'); // opposing-account-name - } - - return $this->row; - } - - /** - * Parses the current description with costs from ABN AMRO itself. - * - * @return bool true if the description is GEA/BEA-format, false otherwise - */ - protected function parseABNAMRODescription(): bool - { - // See if the current description is formatted in ABN AMRO format - if (preg_match('/ABN AMRO.{24} (.*)/', $this->row[7], $matches)) { - $this->row[8] = 'ABN AMRO'; // this one is new (opposing account name) - $this->row[7] = $matches[1]; // this is the description - - return true; - } - - return false; - } - - /** - * Parses the current description in GEA/BEA format. - * - * @return bool true if the description is GEA/BEAformat, false otherwise - */ - protected function parseGEABEADescription(): bool - { - // See if the current description is formatted in GEA/BEA format - if (preg_match('/([BG]EA) +(NR:[a-zA-Z:0-9]+) +([0-9.\/]+) +([^,]*)/', $this->row[7], $matches)) { - // description and opposing account will be the same. - $this->row[8] = $matches[4]; // 'opposing-account-name' - $this->row[7] = $matches[4]; // 'description' - - if ('GEA' === $matches[1]) { - $this->row[7] = 'GEA ' . $matches[4]; // 'description' - } - - return true; - } - - return false; - } - - /** - * Parses the current description in SEPA format. - * - * @return bool true if the description is SEPA format, false otherwise - * - */ - protected function parseSepaDescription(): bool - { - // See if the current description is formatted as a SEPA plain description - if (preg_match('/^SEPA(.{28})/', $this->row[7], $matches)) { - $type = $matches[1]; - $reference = ''; - $name = ''; - $newDescription = ''; - - // SEPA plain descriptions contain several key-value pairs, split by a colon - preg_match_all('/([A-Za-z]+(?=:\s)):\s([A-Za-z 0-9._#-]+(?=\s|$))/', $this->row[7], $matches, PREG_SET_ORDER); - - if (is_array($matches)) { - foreach ($matches as $match) { - $key = $match[1]; - $value = trim($match[2]); - switch (strtoupper($key)) { - case 'OMSCHRIJVING': - $newDescription = $value; - break; - case 'NAAM': - $this->row[8] = $value; - $name = $value; - break; - case 'KENMERK': - $reference = $value; - break; - case 'IBAN': - $this->row[9] = $value; - break; - default: // @codeCoverageIgnore - // Ignore the rest - } - } - } - - // Set a new description for the current transaction. If none was given - // set the description to type, name and reference - $this->row[7] = $newDescription; - if ('' === $newDescription) { - $this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference); - } - - return true; - } - - return false; - } - - /** - * Parses the current description in TRTP format. - * - * @return bool true if the description is TRTP format, false otherwise - * - */ - protected function parseTRTPDescription(): bool - { - // See if the current description is formatted in TRTP format - if (preg_match_all('!\/([A-Z]{3,4})\/([^/]*)!', $this->row[7], $matches, PREG_SET_ORDER)) { - $type = ''; - $name = ''; - $reference = ''; - $newDescription = ''; - - // Search for properties specified in the TRTP format. If no description - // is provided, use the type, name and reference as new description - if (is_array($matches)) { - foreach ($matches as $match) { - $key = $match[1]; - $value = trim($match[2]); - - switch (strtoupper($key)) { - case 'NAME': - $this->row[8] = $value; - break; - case 'REMI': - $newDescription = $value; - break; - case 'IBAN': - $this->row[9] = $value; - break; - case 'EREF': - $reference = $value; - break; - case 'TRTP': - $type = $value; - break; - default: // @codeCoverageIgnore - // Ignore the rest - } - } - - // Set a new description for the current transaction. If none was given - // set the description to type, name and reference - $this->row[7] = $newDescription; - if ('' === $newDescription) { - $this->row[7] = sprintf('%s - %s (%s)', $type, $name, $reference); - } - } - - return true; - } - - return false; - } -} diff --git a/app/Import/Specifics/Belfius.php b/app/Import/Specifics/Belfius.php deleted file mode 100644 index cc208eab31..0000000000 --- a/app/Import/Specifics/Belfius.php +++ /dev/null @@ -1,96 +0,0 @@ - - * - * This file is part of Firefly III (https://github.com/firefly-iii). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Specifics; - -/** - * Class Belfius. - * - * @deprecated - * @codeCoverageIgnore - * - * Fixes Belfius CSV files to: - * - Correct descriptions for recurring transactions so doubles can be detected when the equivalent incoming - * transaction is imported. - * - */ -class Belfius implements SpecificInterface -{ - /** - * Description of this specific fix. - * - * @return string - * @codeCoverageIgnore - */ - public static function getDescription(): string - { - return 'import.specific_belfius_descr'; - } - - /** - * Name of specific fix. - * - * @return string - * @codeCoverageIgnore - */ - public static function getName(): string - { - return 'import.specific_belfius_name'; - } - - /** - * Fixes the description for outgoing recurring transactions so doubles can be detected when the equivalent incoming - * transaction is imported for another bank account. - * - * @return array the row containing the new description - */ - protected static function processRecurringTransactionDescription(array $row): array - { - if (!isset($row[5]) || !isset($row[14])) { - return $row; - } - - $opposingAccountName = $row[5]; - $description = $row[14]; - - preg_match('/DOORLOPENDE OPDRACHT.*\s+' . preg_quote($opposingAccountName, '/') . '\s+(.+)\s+REF.\s*:/', $description, $matches); - - if (isset($matches[1])) { - $row[14] = $matches[1]; - } - - return $row; - } - - /** - * Run the fix. - * - * @param array $row - * - * @return array - * - */ - public function run(array $row): array - { - return Belfius::processRecurringTransactionDescription($row); - } -} diff --git a/app/Import/Specifics/IngBelgium.php b/app/Import/Specifics/IngBelgium.php deleted file mode 100644 index f31ce7b6c6..0000000000 --- a/app/Import/Specifics/IngBelgium.php +++ /dev/null @@ -1,144 +0,0 @@ - - * - * This file is part of Firefly III (https://github.com/firefly-iii). - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as - * published by the Free Software Foundation, either version 3 of the - * License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Specifics; - -/** - * Class IngBelgium. - * - * @deprecated - * @codeCoverageIgnore - * - * Parses the description and opposing account information (IBAN and name) from CSV files for ING Belgium bank accounts. - * - */ -class IngBelgium implements SpecificInterface -{ - /** - * Description of the current specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getDescription(): string - { - return 'import.specific_ingbelgium_descr'; - } - - /** - * Name of the current specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getName(): string - { - return 'import.specific_ingbelgium_name'; - } - - /** - * Gets the description from the transaction details and makes sure structured descriptions are in the - * "+++090/9337/55493+++" format. - * - * @return string the description - */ - protected static function description(string $transactionDetails): string - { - $description = IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/Mededeling:\s*(.+)$/'); - - return IngBelgium::convertStructuredDescriptionToProperFormat($description); - } - - /** - * Gets the opposing account's IBAN from the transaction details. - * - * @return string the opposing account's IBAN - */ - protected static function opposingAccountIban(string $transactionDetails): string - { - return IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/IBAN:\s*(.+?)(?=\s+)/'); - } - - /** - * Gets the opposing account name from the transaction details. - * - * @return string the opposing account name - */ - protected static function opposingAccountName(string $transactionDetails): string - { - return IngBelgium::parseInformationFromTransactionDetails($transactionDetails, '/Van:\s*(.+?)(?=\s{2,})/'); - - } - - /** - * Gets the description and opposing account information (IBAN and name) from the transaction details and adds - * them to the row of data. - * - * @return array the row containing the description and opposing account's IBAN - */ - protected static function processTransactionDetails(array $row): array - { - if (isset($row[9])) { - $transactionDetails = $row[9]; - $row[11] = IngBelgium::opposingAccountName($transactionDetails); - $row[12] = IngBelgium::opposingAccountIban($transactionDetails); - $row[13] = IngBelgium::description($transactionDetails); - } - - return $row; - } - - private static function convertStructuredDescriptionToProperFormat(string $description): string - { - preg_match('/^\*\*\*(\d{3}\/\d{4}\/\d{5})\*\*\*$/', $description, $matches); - if (isset($matches[1])) { - return '+++' . $matches[1] . '+++'; - } - - return $description; - } - - private static function parseInformationFromTransactionDetails(string $transactionDetails, string $regex): string - { - if (isset($transactionDetails)) { - preg_match($regex, $transactionDetails, $matches); - if (isset($matches[1])) { - return trim($matches[1]); - } - } - - return ''; - } - - /** - * Run the specific code. - * - * @param array $row - * - * @return array - * - */ - public function run(array $row): array - { - return IngBelgium::processTransactionDetails($row); - } -} diff --git a/app/Import/Specifics/IngDescription.php b/app/Import/Specifics/IngDescription.php deleted file mode 100644 index 584a129840..0000000000 --- a/app/Import/Specifics/IngDescription.php +++ /dev/null @@ -1,173 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Specifics; - -/** - * Class IngDescription. - * - * @deprecated - * @codeCoverageIgnore - * - * Parses the description from CSV files for Ing bank accounts. - * - * With Mutation 'InternetBankieren', 'Overschrijving', 'Verzamelbetaling' and - * 'Incasso' the Name of Opposing account the Opposing IBAN number are in the - * Description. This class will remove them, and add Name in description by - * 'Betaalautomaat' so those are easily recognizable - */ -class IngDescription implements SpecificInterface -{ - /** @var array The current row. */ - public $row; - - /** - * Description of the current specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getDescription(): string - { - return 'import.specific_ing_descr'; - } - - /** - * Name of the current specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getName(): string - { - return 'import.specific_ing_name'; - } - - /** - * Run the specific code. - * - * @param array $row - * - * @return array - * - */ - public function run(array $row): array - { - $this->row = array_values($row); - array_push($this->row); // New column for "Valutadatum" - if (count($this->row) >= 8) { // check if the array is correct - switch ($this->row[4]) { // Get value for the mutation type - case 'GT': // InternetBankieren - case 'OV': // Overschrijving - case 'VZ': // Verzamelbetaling - case 'IC': // Incasso - case 'DV': // Divers - $this->removeIBANIngDescription(); // Remove "IBAN:", because it is already at "Tegenrekening" - $this->removeNameIngDescription(); // Remove "Naam:", because it is already at "Naam/ Omschrijving" - $this->removeIngDescription(); // Remove "Omschrijving", but not the value from description - $this->moveValutadatumDescription(); // Move "Valutadatum" from description to new column - $this->MoveSavingsAccount(); // Move savings account number and name - break; - case 'BA': // Betaalautomaat - $this->moveValutadatumDescription(); // Move "Valutadatum" from description to new column - $this->addNameIngDescription(); - break; - } - } - - return $this->row; - } - - /** - * Add the Opposing name from cell 1 in the description for Betaalautomaten - * Otherwise the description is only: 'Pasvolgnr: Transactie: Term:'. - */ - protected function addNameIngDescription(): void - { - $this->row[8] = $this->row[1] . ' ' . $this->row[8]; - } - - /** - * Move "Valutadatum" from the description to new column. - */ - protected function moveValutadatumDescription(): void - { - $matches = []; - if (preg_match('/Valutadatum: ([0-9-]+)/', $this->row[8], $matches)) { - $this->row[9] = date("Ymd", strtotime($matches[1])); - $this->row[8] = preg_replace('/Valutadatum: [0-9-]+/', '', $this->row[8]); - } - } - - /** - * Remove IBAN number out of the description - * Default description of Description is: Naam: Omschrijving: IBAN: . - */ - protected function removeIBANIngDescription(): void - { - // Try replace the iban number with nothing. The IBAN nr is found in the third column - $this->row[8] = preg_replace('/\sIBAN:\s' . $this->row[3] . '/', '', $this->row[8]); - } - - /** - * Remove "Omschrijving" (and NOT its value) from the description. - */ - protected function removeIngDescription(): void - { - $this->row[8] = preg_replace('/Omschrijving: /', '', $this->row[8]); - } - - /** - * Remove "Naam" (and its value) from the description. - */ - protected function removeNameIngDescription(): void - { - $this->row[8] = preg_replace('/Naam:.*?([a-zA-Z\/]+:)/', '$1', $this->row[8]); - } - - /** - * Move savings account number to column 1 and name to column 3. - */ - private function MoveSavingsAccount(): void - { - $matches = []; - - if (preg_match('/(Naar|Van) (.*rekening) ([A-Za-z0-9]+)/', $this->row[8], $matches)) { // Search for saving acount at 'Mededelingen' column - $this->row[1] = $this->row[1] . ' ' . $matches[2] . ' ' . $matches[3]; // Current name + Saving acount name + Acount number - if ('' === (string) $this->row[3]) { // if Saving account number does not yet exists - $this->row[3] = $matches[3]; // Copy savings account number - } - $this->row[8] = preg_replace('/(Naar|Van) (.*rekening) ([A-Za-z0-9]+)/', '', $this->row[8]); // Remove the savings account content from description - } elseif (preg_match('/(Naar|Van) (.*rekening) ([A-Za-z0-9]+)/', $this->row[1], $matches)) { // Search for saving acount at 'Naam / Omschrijving' column - $this->row[1] = $matches[2] . ' ' . $matches[3]; // Saving acount name + Acount number - if ('' === (string) $this->row[3]) { // if Saving account number does not yet exists - $this->row[3] = $matches[3]; // Copy savings account number - } - } - - if ('' !== (string)$this->row[3]) { // if Saving account number exists - if (! preg_match('/[A-Za-z]/', $this->row[3])) { // if Saving account number has no characters - $this->row[3] = sprintf("%010d", $this->row[3]); // Make the number 10 digits - } - } - } -} diff --git a/app/Import/Specifics/PresidentsChoice.php b/app/Import/Specifics/PresidentsChoice.php deleted file mode 100644 index 36abe52657..0000000000 --- a/app/Import/Specifics/PresidentsChoice.php +++ /dev/null @@ -1,77 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Specifics; - -/** - * Class PresidentsChoice. - * - * @deprecated - * @codeCoverageIgnore - */ -class PresidentsChoice implements SpecificInterface -{ - /** - * Description of specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getDescription(): string - { - return 'import.specific_pres_descr'; - } - - /** - * Name of specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getName(): string - { - return 'import.specific_pres_name'; - } - - /** - * Run this specific. - * - * @param array $row - * - * @return array - */ - public function run(array $row): array - { - $row = array_values($row); - // first, if column 2 is empty and 3 is not, do nothing. - // if column 3 is empty and column 2 is not, move amount to column 3, *-1 - if (isset($row[3]) && '' === $row[3]) { - $row[3] = bcmul($row[2], '-1'); - } - if (isset($row[1])) { - // copy description into column 2, which is now usable. - $row[2] = $row[1]; - } - - return $row; - } -} diff --git a/app/Import/Specifics/SnsDescription.php b/app/Import/Specifics/SnsDescription.php deleted file mode 100644 index f36a683ee5..0000000000 --- a/app/Import/Specifics/SnsDescription.php +++ /dev/null @@ -1,73 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Specifics; - -/** - * Class SnsDescription. - * - * @codeCoverageIgnore - * @deprecated - */ -class SnsDescription implements SpecificInterface -{ - /** - * Get description of specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getDescription(): string - { - return 'import.specific_sns_descr'; - } - - /** - * Get name of specific. - * - * @return string - * @codeCoverageIgnore - */ - public static function getName(): string - { - return 'import.specific_sns_name'; - } - - /** - * Run specific. - * - * @param array $row - * - * @return array - */ - public function run(array $row): array - { - $row = array_values($row); - if (!isset($row[17])) { - return $row; - } - $row[17] = ltrim($row[17], "'"); - $row[17] = rtrim($row[17], "'"); - - return $row; - } -} diff --git a/app/Import/Specifics/SpecificInterface.php b/app/Import/Specifics/SpecificInterface.php deleted file mode 100644 index b2a9a6e5fa..0000000000 --- a/app/Import/Specifics/SpecificInterface.php +++ /dev/null @@ -1,55 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Import\Specifics; - -/** - * Interface SpecificInterface. - * - * @codeCoverageIgnore - * @deprecated - */ -interface SpecificInterface -{ - /** - * Get description. - * - * @return string - */ - public static function getDescription(): string; - - /** - * Get name. - * - * @return string - */ - public static function getName(): string; - - /** - * Run specific. - * - * @param array $row - * - * @return array - */ - public function run(array $row): array; -} diff --git a/app/Import/Storage/ImportArrayStorage.php b/app/Import/Storage/ImportArrayStorage.php deleted file mode 100644 index c73ec54186..0000000000 --- a/app/Import/Storage/ImportArrayStorage.php +++ /dev/null @@ -1,630 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Import\Storage; - -use Carbon\Carbon; -use DB; -use Exception; -use FireflyIII\Events\RequestedReportOnJournals; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Collector\GroupCollectorInterface; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\Preference; -use FireflyIII\Models\TransactionGroup; -use FireflyIII\Models\TransactionJournal; -use FireflyIII\Models\TransactionType; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Repositories\Journal\JournalRepositoryInterface; -use FireflyIII\Repositories\Tag\TagRepositoryInterface; -use FireflyIII\Repositories\TransactionGroup\TransactionGroupRepositoryInterface; -use FireflyIII\TransactionRules\Engine\RuleEngine; -use Illuminate\Database\QueryException; -use Illuminate\Support\Collection; -use Log; - -/** - * Creates new transactions based on arrays. - * - * Class ImportArrayStorage - * - * @codeCoverageIgnore - * @deprecated - * - */ -class ImportArrayStorage -{ - /** @var int Number of hits required for a transfer to match. */ - private const REQUIRED_HITS = 4; - /** @var bool Check for transfers during import. */ - private $checkForTransfers = false; - /** @var TransactionGroupRepositoryInterface */ - private $groupRepos; - /** @var ImportJob The import job */ - private $importJob; - /** @var JournalRepositoryInterface Journal repository for storage. */ - private $journalRepos; - /** @var string */ - private $language = 'en_US'; - /** @var ImportJobRepositoryInterface Import job repository */ - private $repository; - /** @var array The transfers the user already has. */ - private $transfers; - - /** - * Set job, count transfers in the array and create the repository. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - - $this->countTransfers(); - - $this->journalRepos = app(JournalRepositoryInterface::class); - $this->journalRepos->setUser($importJob->user); - - $this->groupRepos = app(TransactionGroupRepositoryInterface::class); - $this->groupRepos->setUser($importJob->user); - - // get language of user. - /** @var Preference $pref */ - $pref = app('preferences')->getForUser($importJob->user, 'language', config('firefly.default_language', 'en_US')); - $this->language = $pref->data; - - Log::debug('Constructed ImportArrayStorage()'); - } - - /** - * Actually does the storing. Does three things. - * - Store journals - * - Link to tag - * - Run rules (if set to) - * - * @throws FireflyException - * @return Collection - */ - public function store(): Collection - { - // store transactions - $this->setStatus('storing_data'); - $collection = $this->storeGroupArray(); - $this->setStatus('stored_data'); - - // link tag: - $this->setStatus('linking_to_tag'); - $this->linkToTag($collection); - $this->setStatus('linked_to_tag'); - - // run rules, if configured to. - $config = $this->importJob->configuration; - if (isset($config['apply-rules']) && true === $config['apply-rules']) { - $this->setStatus('applying_rules'); - $this->applyRules($collection); - $this->setStatus('rules_applied'); - } - - app('preferences')->mark(); - - // email about this: - event(new RequestedReportOnJournals((int) $this->importJob->user_id, $collection)); - - return $collection; - } - - /** - * Applies the users rules to the created journals. - * - * @param Collection $collection - * - */ - private function applyRules(Collection $collection): void - { - Log::debug('Now in applyRules()'); - - /** @var RuleEngine $ruleEngine */ - $ruleEngine = app(RuleEngine::class); - $ruleEngine->setUser($this->importJob->user); - $ruleEngine->setAllRules(true); - - // for this call, the rule engine only includes "store" rules: - $ruleEngine->setTriggerMode(RuleEngine::TRIGGER_STORE); - Log::debug('Start of engine loop'); - foreach ($collection as $group) { - $this->applyRulesGroup($ruleEngine, $group); - } - Log::debug('End of engine loop.'); - } - - /** - * @param RuleEngine $ruleEngine - * @param TransactionGroup $group - */ - private function applyRulesGroup(RuleEngine $ruleEngine, TransactionGroup $group): void - { - Log::debug(sprintf('Processing group #%d', $group->id)); - foreach ($group->transactionJournals as $journal) { - Log::debug(sprintf('Processing journal #%d from group #%d', $journal->id, $group->id)); - $ruleEngine->processTransactionJournal($journal); - } - } - - /** - * Count the number of transfers in the array. If this is zero, don't bother checking for double transfers. - */ - private function countTransfers(): void - { - Log::debug('Now in countTransfers()'); - /** @var array $array */ - $array = $this->repository->getTransactions($this->importJob); - - - $count = 0; - foreach ($array as $index => $group) { - - foreach ($group['transactions'] as $transaction) { - if (strtolower(TransactionType::TRANSFER) === strtolower($transaction['type'])) { - $count++; - Log::debug(sprintf('Row #%d is a transfer, increase count to %d', $index + 1, $count)); - } - } - } - Log::debug(sprintf('Count of transfers in import array is %d.', $count)); - if ($count > 0) { - $this->checkForTransfers = true; - Log::debug('Will check for duplicate transfers.'); - // get users transfers. Needed for comparison. - $this->getTransfers(); - } - } - - /** - * @param int $index - * @param array $group - * - * @return bool - */ - private function duplicateDetected(int $index, array $group): bool - { - Log::debug(sprintf('Now in duplicateDetected(%d)', $index)); - $transactions = $group['transactions'] ?? []; - foreach ($transactions as $transaction) { - $hash = $this->getHash($transaction); - $existingId = $this->hashExists($hash); - if (null !== $existingId) { - $message = (string) trans('import.duplicate_row', ['row' => $index, 'description' => $transaction['description']]); - $this->logDuplicateObject($transaction, $existingId); - $this->repository->addErrorMessage($this->importJob, $message); - - return true; - } - - // do transfer detection: - if ($this->checkForTransfers && $this->transferExists($transaction)) { - $message = (string) trans('import.duplicate_row', ['row' => $index, 'description' => $transaction['description']]); - $this->logDuplicateTransfer($transaction); - $this->repository->addErrorMessage($this->importJob, $message); - - return true; - } - } - - return false; - } - - /** - * Get hash of transaction. - * - * @param array $transaction - * - * @return string - */ - private function getHash(array $transaction): string - { - unset($transaction['import_hash_v2'], $transaction['original_source']); - $json = json_encode($transaction, JSON_THROW_ON_ERROR); - if (false === $json) { - // @codeCoverageIgnoreStart - /** @noinspection ForgottenDebugOutputInspection */ - Log::error('Could not encode import array.', $transaction); - try { - $json = random_int(1, 10000); - } catch (Exception $e) { - // seriously? - Log::error(sprintf('random_int() just failed. I want a medal: %s', $e->getMessage())); - } - // @codeCoverageIgnoreEnd - } - - $hash = hash('sha256', $json); - Log::debug(sprintf('The hash is: %s', $hash), $transaction); - - return $hash; - } - - /** - * @param TransactionGroup $transactionGroup - * - * @return array - */ - private function getTransactionFromJournal(TransactionGroup $transactionGroup): array - { - // collect transactions using the journal collector - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - - $collector->setUser($this->importJob->user); - $collector->setGroup($transactionGroup); - - return $collector->getExtractedJournals(); - } - - /** - * Get the users transfers, so they can be compared to whatever the user is trying to import. - */ - private function getTransfers(): void - { - Log::debug('Now in getTransfers()'); - app('preferences')->mark(); - - /** @var GroupCollectorInterface $collector */ - $collector = app(GroupCollectorInterface::class); - - $collector->setUser($this->importJob->user); - $collector - ->setTypes([TransactionType::TRANSFER])->setLimit(10000)->setPage(1) - ->withAccountInformation(); - $this->transfers = $collector->getExtractedJournals(); - Log::debug(sprintf('Count of getTransfers() is %d', count($this->transfers))); - } - - /** - * Check if the hash exists for the array the user wants to import. - * - * @param string $hash - * - * @return int|null - */ - private function hashExists(string $hash): ?int - { - $entry = $this->journalRepos->findByHash($hash); - if (null === $entry) { - Log::debug(sprintf('Found no transactions with hash %s.', $hash)); - - return null; - } - Log::info(sprintf('Found a transaction journal with an existing hash: %s', $hash)); - - return (int) $entry->transaction_journal_id; - } - - /** - * Link all imported journals to a tag. - * - * @param Collection $collection - */ - private function linkToTag(Collection $collection): void - { - if (0 === $collection->count()) { - return; - } - /** @var TagRepositoryInterface $repository */ - $repository = app(TagRepositoryInterface::class); - $repository->setUser($this->importJob->user); - $data = [ - 'tag' => (string) trans('import.import_with_key', ['key' => $this->importJob->key]), - 'date' => new Carbon, - 'description' => null, - 'latitude' => null, - 'longitude' => null, - 'zoom_level' => null, - 'tagMode' => 'nothing', - ]; - $tag = $repository->store($data); - - Log::debug(sprintf('Created tag #%d ("%s")', $tag->id, $tag->tag)); - Log::debug('Looping groups...'); - - // TODO double loop. - - /** @var TransactionGroup $group */ - foreach ($collection as $group) { - Log::debug(sprintf('Looping journals in group #%d', $group->id)); - /** @var TransactionJournal $journal */ - $journalIds = $group->transactionJournals->pluck('id')->toArray(); - $tagId = $tag->id; - foreach ($journalIds as $journalId) { - Log::debug(sprintf('Linking journal #%d to tag #%d...', $journalId, $tagId)); - // @codeCoverageIgnoreStart - try { - DB::table('tag_transaction_journal')->insert(['transaction_journal_id' => $journalId, 'tag_id' => $tagId]); - } catch (QueryException $e) { - Log::error(sprintf('Could not link journal #%d to tag #%d because: %s', $journalId, $tagId, $e->getMessage())); - } - // @codeCoverageIgnoreEnd - } - Log::info(sprintf('Linked %d journals to tag #%d ("%s")', $collection->count(), $tag->id, $tag->tag)); - } - $this->repository->setTag($this->importJob, $tag); - - } - - /** - * Log about a duplicate object (double hash). - * - * @param array $transaction - * @param int $existingId - */ - private function logDuplicateObject(array $transaction, int $existingId): void - { - Log::info( - 'Transaction is a duplicate, and will not be imported (the hash exists).', - [ - 'existing' => $existingId, - 'description' => $transaction['description'] ?? '', - 'amount' => $transaction['transactions'][0]['amount'] ?? 0, - 'date' => $transaction['date'] ?? '', - ] - ); - - } - - /** - * Log about a duplicate transfer. - * - * @param array $transaction - */ - private function logDuplicateTransfer(array $transaction): void - { - Log::info( - 'Transaction is a duplicate transfer, and will not be imported (such a transfer exists already).', - [ - 'description' => $transaction['description'] ?? '', - 'amount' => $transaction['transactions'][0]['amount'] ?? 0, - 'date' => $transaction['date'] ?? '', - ] - ); - } - - /** - * Shorthand method to quickly set job status - * - * @param string $status - */ - private function setStatus(string $status): void - { - $this->repository->setStatus($this->importJob, $status); - } - - /** - * @param int $index - * @param array $group - * - * @return TransactionGroup|null - */ - private function storeGroup(int $index, array $group): ?TransactionGroup - { - Log::debug(sprintf('Going to store entry #%d', $index + 1)); - - // do some basic error catching. - foreach ($group['transactions'] as $groupIndex => $transaction) { - $group['transactions'][$groupIndex]['date'] = Carbon::parse($transaction['date'], config('app.timezone')); - $group['transactions'][$groupIndex]['description'] = '' === $transaction['description'] ? '(empty description)' : $transaction['description']; - } - - // do duplicate detection! - if ($this->duplicateDetected($index, $group)) { - Log::warning(sprintf('Row #%d seems to be a imported already and will be ignored.', $index)); - - return null; - } - - // store the group - try { - $newGroup = $this->groupRepos->store($group); - // @codeCoverageIgnoreStart - } catch (FireflyException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - $this->repository->addErrorMessage($this->importJob, sprintf('Row #%d could not be imported. %s', $index, $e->getMessage())); - - return null; - } - // @codeCoverageIgnoreEnd - Log::debug(sprintf('Stored as group #%d', $newGroup->id)); - - // add to collection of transfers, if necessary: - if ('transfer' === strtolower($group['transactions'][0]['type'])) { - $journals = $this->getTransactionFromJournal($newGroup); - Log::debug('We just stored a transfer, so add the journal to the list of transfers.'); - foreach ($journals as $newJournal) { - $this->transfers[] = $newJournal; - } - Log::debug(sprintf('List length is now %d', count($this->transfers))); - } - - return $newGroup; - } - - /** - * Store array as journals. - * - * @throws FireflyException - * - * @return Collection - */ - private function storeGroupArray(): Collection - { - /** @var array $array */ - $array = $this->repository->getTransactions($this->importJob); - $count = count($array); - - Log::notice(sprintf('Will now store the groups. Count of groups is %d.', $count)); - Log::notice('Going to store...'); - - $collection = new Collection; - foreach ($array as $index => $group) { - Log::debug(sprintf('Now store #%d', $index + 1)); - $result = $this->storeGroup($index, $group); - if (null !== $result) { - $collection->push($result); - } - } - Log::notice(sprintf('Done storing. Firefly III has stored %d transactions.', $collection->count())); - - return $collection; - } - - /** - * Check if a transfer exists. - * - * @param array $transaction - * - * @return bool - * - */ - private function transferExists(array $transaction): bool - { - Log::debug('transferExists() Check if transaction is a double transfer.'); - - // how many hits do we need? - Log::debug(sprintf('System has %d existing transfers', count($this->transfers))); - // loop over each split: - - // check if is a transfer - if (strtolower(TransactionType::TRANSFER) !== strtolower($transaction['type'])) { - // @codeCoverageIgnoreStart - Log::debug(sprintf('Is a %s, not a transfer so no.', $transaction['type'])); - - return false; - // @codeCoverageIgnoreEnd - } - - - Log::debug(sprintf('Required hits for transfer comparison is %d', self::REQUIRED_HITS)); - - // get the amount: - /** @noinspection UnnecessaryCastingInspection */ - $amount = (string) ($transaction['amount'] ?? '0'); - if (bccomp($amount, '0') === -1) { - $amount = bcmul($amount, '-1'); // @codeCoverageIgnore - } - - // get the description: - //$description = '' === (string)$transaction['description'] ? $transaction['description'] : $transaction['description']; - $description = (string) $transaction['description']; - - // get the source and destination ID's: - $transactionSourceIDs = [(int) $transaction['source_id'], (int) $transaction['destination_id']]; - sort($transactionSourceIDs); - - // get the source and destination names: - $transactionSourceNames = [(string) $transaction['source_name'], (string) $transaction['destination_name']]; - sort($transactionSourceNames); - - // then loop all transfers: - /** @var array $transfer */ - foreach ($this->transfers as $transfer) { - // number of hits for this split-transfer combination: - $hits = 0; - Log::debug(sprintf('Now looking at transaction journal #%d', $transfer['transaction_journal_id'])); - // compare amount: - $originalAmount = app('steam')->positive($transfer['amount']); - Log::debug(sprintf('Amount %s compared to %s', $amount, $originalAmount)); - if (0 !== bccomp($amount, $originalAmount)) { - Log::debug('Amount is not a match, continue with next transfer.'); - continue; - } - ++$hits; - Log::debug(sprintf('Comparison is a hit! (%s)', $hits)); - - // compare description: - // $comparison = '(empty description)' === $transfer['description'] ? '' : $transfer['description']; - $comparison = $transfer['description']; - Log::debug(sprintf('Comparing "%s" to "%s" (original: "%s")', $description, $transfer['description'], $comparison)); - if ($description !== $comparison) { - Log::debug('Description is not a match, continue with next transfer.'); - continue; // @codeCoverageIgnore - } - ++$hits; - Log::debug(sprintf('Comparison is a hit! (%s)', $hits)); - - // compare date: - $transferDate = $transfer['date']->format('Y-m-d H:i:s'); - $transactionDate = $transaction['date']->format('Y-m-d H:i:s'); - Log::debug(sprintf('Comparing dates "%s" to "%s"', $transactionDate, $transferDate)); - if ($transactionDate !== $transferDate) { - Log::debug('Date is not a match, continue with next transfer.'); - continue; // @codeCoverageIgnore - } - ++$hits; - Log::debug(sprintf('Comparison is a hit! (%s)', $hits)); - - // compare source and destination id's - $transferSourceIDs = [(int) $transfer['source_account_id'], (int) $transfer['destination_account_id']]; - sort($transferSourceIDs); - /** @noinspection DisconnectedForeachInstructionInspection */ - Log::debug('Comparing current transaction source+dest IDs', $transactionSourceIDs); - Log::debug('.. with current transfer source+dest IDs', $transferSourceIDs); - if ($transactionSourceIDs === $transferSourceIDs) { - ++$hits; - Log::debug(sprintf('Source IDs are the same! (%d)', $hits)); - } - if ($transactionSourceIDs !== $transferSourceIDs) { - Log::debug('Source IDs are not the same.'); - } - unset($transferSourceIDs); - - // compare source and destination names - $transferSource = [(string) ($transfer['source_account_name'] ?? ''), (string) ($transfer['destination_account_name'] ?? '')]; - sort($transferSource); - /** @noinspection DisconnectedForeachInstructionInspection */ - Log::debug('Comparing current transaction source+dest names', $transactionSourceNames); - Log::debug('.. with current transfer source+dest names', $transferSource); - if ($transactionSourceNames === $transferSource && $transferSource !== ['', '']) { - // @codeCoverageIgnoreStart - ++$hits; - Log::debug(sprintf('Source names are the same! (%d)', $hits)); - // @codeCoverageIgnoreEnd - } - if ($transactionSourceNames !== $transferSource) { - Log::debug('Source names are not the same.'); - } - - Log::debug(sprintf('Number of hits is %d', $hits)); - if ($hits >= self::REQUIRED_HITS) { - Log::debug(sprintf('Is more than %d, return true.', self::REQUIRED_HITS)); - - return true; - } - } - Log::debug('Is not an existing transfer, return false.'); - - return false; - } - -} diff --git a/app/Models/ImportJob.php b/app/Models/ImportJob.php deleted file mode 100644 index fd43e2c4be..0000000000 --- a/app/Models/ImportJob.php +++ /dev/null @@ -1,150 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Models; - -use Carbon\Carbon; -use Eloquent; -use FireflyIII\User; -use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Eloquent\Collection; -use Illuminate\Database\Eloquent\Model; -use Illuminate\Database\Eloquent\Relations\BelongsTo; -use Illuminate\Database\Eloquent\Relations\MorphMany; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - -/** - * Class ImportJob. - * - * @codeCoverageIgnore - * @deprecated - * @property array $transactions - * @property array $configuration - * @property User $user - * @property int $user_id - * @property string $status - * @property string $stage - * @property string $key - * @property string $provider - * @property string $file_type - * @property int $tag_id - * @property Tag $tag - * @property array $errors - * @property array extended_status - * @property int id - * @property Carbon $created_at - * @property Carbon $updated_at - * @property-read Collection|Attachment[] $attachments - * @method static Builder|ImportJob newModelQuery() - * @method static Builder|ImportJob newQuery() - * @method static Builder|ImportJob query() - * @method static Builder|ImportJob whereConfiguration($value) - * @method static Builder|ImportJob whereCreatedAt($value) - * @method static Builder|ImportJob whereErrors($value) - * @method static Builder|ImportJob whereExtendedStatus($value) - * @method static Builder|ImportJob whereFileType($value) - * @method static Builder|ImportJob whereId($value) - * @method static Builder|ImportJob whereKey($value) - * @method static Builder|ImportJob whereProvider($value) - * @method static Builder|ImportJob whereStage($value) - * @method static Builder|ImportJob whereStatus($value) - * @method static Builder|ImportJob whereTagId($value) - * @method static Builder|ImportJob whereTransactions($value) - * @method static Builder|ImportJob whereUpdatedAt($value) - * @method static Builder|ImportJob whereUserId($value) - * @mixin Eloquent - * @property-read int|null $attachments_count - * @property int $id - * @property array|null $extended_status - */ -class ImportJob extends Model -{ - - /** - * The attributes that should be casted to native types. - * - * @var array - */ - protected $casts - = [ - 'user_id' => 'int', - 'created_at' => 'datetime', - 'updated_at' => 'datetime', - 'configuration' => 'array', - 'extended_status' => 'array', - 'transactions' => 'array', - 'errors' => 'array', - ]; - /** @var array Fields that can be filled */ - protected $fillable = ['key', 'user_id', 'file_type', 'provider', 'status', 'stage', 'configuration', 'extended_status', 'transactions', 'errors']; - - /** - * Route binder. Converts the key in the URL to the specified object (or throw 404). - * - * @param $value - * - * @throws NotFoundHttpException - * @return mixed - * - */ - public static function routeBinder(string $value): ImportJob - { - if (auth()->check()) { - $key = trim($value); - /** @var User $user */ - $user = auth()->user(); - /** @var ImportJob $importJob */ - $importJob = $user->importJobs()->where('key', $key)->first(); - if (null !== $importJob) { - return $importJob; - } - } - throw new NotFoundHttpException; - } - - /** - * @codeCoverageIgnore - * @return MorphMany - */ - public function attachments(): MorphMany - { - return $this->morphMany(Attachment::class, 'attachable'); - } - - /** - * @codeCoverageIgnore - * @return BelongsTo - */ - public function tag(): BelongsTo - { - return $this->belongsTo(Tag::class); - } - - /** - * @codeCoverageIgnore - * @return BelongsTo - */ - public function user(): BelongsTo - { - return $this->belongsTo(User::class); - } -} diff --git a/app/Models/ObjectGroup.php b/app/Models/ObjectGroup.php index 74a4dc3647..953fafde0e 100644 --- a/app/Models/ObjectGroup.php +++ b/app/Models/ObjectGroup.php @@ -4,13 +4,50 @@ declare(strict_types=1); namespace FireflyIII\Models; +use FireflyIII\User; use Illuminate\Database\Eloquent\Model; +use Illuminate\Database\Eloquent\Relations\BelongsTo; +use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; /** * Class ObjectGroup + * + * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\PiggyBank[] $piggyBanks + * @property-read int|null $piggy_banks_count + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup newModelQuery() + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup newQuery() + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup query() + * @mixin \Eloquent + * @property int $id + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property string|null $deleted_at + * @property string $title + * @property int $order + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereCreatedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereDeletedAt($value) + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereId($value) + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereOrder($value) + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereTitle($value) + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\Models\ObjectGroup whereUpdatedAt($value) */ class ObjectGroup extends Model { + protected $fillable = ['title', 'order', 'user_id']; + + /** + * The attributes that should be casted to native types. + * + * @var array + */ + protected $casts + = [ + 'created_at' => 'datetime', + 'updated_at' => 'datetime', + 'user_id' => 'integer', + 'deleted_at' => 'datetime', + ]; + /** * @return \Illuminate\Database\Eloquent\Relations\MorphToMany */ @@ -18,4 +55,34 @@ class ObjectGroup extends Model { return $this->morphedByMany(PiggyBank::class, 'object_groupable'); } + + /** + * Route binder. Converts the key in the URL to the specified object (or throw 404). + * + * @param string $value + * + * @throws NotFoundHttpException + * @return ObjectGroup + */ + public static function routeBinder(string $value): ObjectGroup + { + if (auth()->check()) { + $objectGroupId = (int) $value; + $objectGroup = self::where('object_groups.id', $objectGroupId) + ->where('object_groups.user_id', auth()->user()->id)->first(); + if (null !== $objectGroup) { + return $objectGroup; + } + } + throw new NotFoundHttpException; + } + + /** + * @return BelongsTo + * @codeCoverageIgnore + */ + public function user(): BelongsTo + { + return $this->belongsTo(User::class); + } } diff --git a/app/Models/PiggyBank.php b/app/Models/PiggyBank.php index 4b9f3af2f8..64770b88ac 100644 --- a/app/Models/PiggyBank.php +++ b/app/Models/PiggyBank.php @@ -78,6 +78,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read int|null $notes_count * @property-read int|null $piggy_bank_events_count * @property-read int|null $piggy_bank_repetitions_count + * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\ObjectGroup[] $objectGroups + * @property-read int|null $object_groups_count */ class PiggyBank extends Model { diff --git a/app/Models/Recurrence.php b/app/Models/Recurrence.php index 59444cfaf1..47956a6b8e 100644 --- a/app/Models/Recurrence.php +++ b/app/Models/Recurrence.php @@ -189,6 +189,15 @@ class Recurrence extends Model return $this->belongsTo(TransactionCurrency::class); } + /** + * @codeCoverageIgnore + * @return MorphMany + */ + public function attachments(): MorphMany + { + return $this->morphMany(Attachment::class, 'attachable'); + } + /** * @codeCoverageIgnore * @return BelongsTo diff --git a/app/Models/Tag.php b/app/Models/Tag.php index 1a7834771e..45c56c3368 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -78,6 +78,13 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read \Illuminate\Database\Eloquent\Collection|Location[] $locations * @property-read int|null $locations_count * @property-read int|null $transaction_journals_count + * @property \Illuminate\Support\Carbon|null $created_at + * @property \Illuminate\Support\Carbon|null $updated_at + * @property string $tagMode + * @property string|null $description + * @property float|null $latitude + * @property float|null $longitude + * @property int|null $zoomLevel */ class Tag extends Model { diff --git a/app/Models/TransactionCurrency.php b/app/Models/TransactionCurrency.php index 8d1ca509af..5b05bc9cd5 100644 --- a/app/Models/TransactionCurrency.php +++ b/app/Models/TransactionCurrency.php @@ -67,7 +67,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read int|null $budget_limits_count * @property-read int|null $transaction_journals_count * @property-read int|null $transactions_count - * @property string $name */ class TransactionCurrency extends Model { diff --git a/app/Models/TransactionJournal.php b/app/Models/TransactionJournal.php index 637d68e2b0..74e548e7c7 100644 --- a/app/Models/TransactionJournal.php +++ b/app/Models/TransactionJournal.php @@ -121,18 +121,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read int|null $transaction_journal_meta_count * @property-read int|null $transactions_count * @method static EloquentBuilder|TransactionJournal whereTransactionGroupId($value) - * @property int $user_id - * @property int|null $transaction_group_id - * @property int|null $transaction_currency_id - * @property \Illuminate\Support\Carbon|null $interest_date - * @property \Illuminate\Support\Carbon|null $book_date - * @property \Illuminate\Support\Carbon|null $process_date - * @property int $order - * @property bool $encrypted - * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Budget[] $budgets - * @property-read \FireflyIII\Models\TransactionGroup|null $transactionGroup - * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\TransactionJournalMeta[] $transactionJournalMeta - * @property-read \Illuminate\Database\Eloquent\Collection|\FireflyIII\Models\Transaction[] $transactions */ class TransactionJournal extends Model { diff --git a/app/Providers/AuthServiceProvider.php b/app/Providers/AuthServiceProvider.php index 0f35e75e9c..96594e826b 100644 --- a/app/Providers/AuthServiceProvider.php +++ b/app/Providers/AuthServiceProvider.php @@ -22,8 +22,12 @@ declare(strict_types=1); namespace FireflyIII\Providers; +use FireflyIII\Support\Authentication\RemoteUserGuard; +use FireflyIII\Support\Authentication\RemoteUserProvider; use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider; +use Illuminate\Support\Facades\Auth; use Laravel\Passport\Passport; +use Log; /** * @codeCoverageIgnore @@ -48,11 +52,26 @@ class AuthServiceProvider extends ServiceProvider */ public function boot(): void { + Auth::provider( + 'remote_user_provider', function ($app, array $config) { + //Log::debug('Creating remote_user_provider in Closure'); + return new RemoteUserProvider($app, $config); + } + ); + + Auth::extend( + 'remote_user_guard', static function ($app, string $name, array $config) { + //Log::debug('Creating remote_user_guard in Closure'); + return new RemoteUserGuard(Auth::createUserProvider($config['provider']), $app); + } + ); + $this->registerPolicies(); + + Passport::routes(); Passport::tokensExpireIn(now()->addDays(14)); - // } } diff --git a/app/Providers/FireflyServiceProvider.php b/app/Providers/FireflyServiceProvider.php index e489379798..45a6993393 100644 --- a/app/Providers/FireflyServiceProvider.php +++ b/app/Providers/FireflyServiceProvider.php @@ -37,6 +37,8 @@ use FireflyIII\Helpers\Report\PopupReport; use FireflyIII\Helpers\Report\PopupReportInterface; use FireflyIII\Helpers\Report\ReportHelper; use FireflyIII\Helpers\Report\ReportHelperInterface; +use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepository; +use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface; use FireflyIII\Repositories\Telemetry\TelemetryRepository; use FireflyIII\Repositories\Telemetry\TelemetryRepositoryInterface; use FireflyIII\Repositories\TransactionType\TransactionTypeRepository; @@ -62,6 +64,7 @@ use FireflyIII\Support\Preferences; use FireflyIII\Support\Steam; use FireflyIII\Support\Telemetry; use FireflyIII\Validation\FireflyValidator; +use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; use Validator; @@ -172,8 +175,23 @@ class FireflyServiceProvider extends ServiceProvider // other generators $this->app->bind(UserRepositoryInterface::class, UserRepository::class); $this->app->bind(TransactionTypeRepositoryInterface::class, TransactionTypeRepository::class); + $this->app->bind(AttachmentHelperInterface::class, AttachmentHelper::class); + + $this->app->bind( + ObjectGroupRepositoryInterface::class, + static function (Application $app) { + /** @var ObjectGroupRepository $repository */ + $repository = app(ObjectGroupRepository::class); + if ($app->auth->check()) { + $repository->setUser(auth()->user()); + } + + return $repository; + } + ); + // more generators: $this->app->bind(PopupReportInterface::class, PopupReport::class); $this->app->bind(HelpInterface::class, Help::class); @@ -182,7 +200,7 @@ class FireflyServiceProvider extends ServiceProvider $this->app->bind(UpdateRequestInterface::class, UpdateRequest::class); $this->app->bind(TelemetryRepositoryInterface::class, TelemetryRepository::class); - $class = (string)config(sprintf('firefly.cer_providers.%s', (string)config('firefly.cer_provider'))); + $class = (string) config(sprintf('firefly.cer_providers.%s', (string) config('firefly.cer_provider'))); if ('' === $class) { throw new FireflyException('Invalid currency exchange rate provider. Cannot continue.'); } diff --git a/app/Providers/ImportServiceProvider.php b/app/Providers/ImportServiceProvider.php deleted file mode 100644 index 6e2fcc79a2..0000000000 --- a/app/Providers/ImportServiceProvider.php +++ /dev/null @@ -1,62 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Providers; - -use FireflyIII\Repositories\ImportJob\ImportJobRepository; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Foundation\Application; -use Illuminate\Support\ServiceProvider; - -/** - * @codeCoverageIgnore - * Class ImportServiceProvider. - * @deprecated - */ -class ImportServiceProvider extends ServiceProvider -{ - /** - * Bootstrap the application services. - */ - public function boot(): void - { - } - - /** - * Register the application services. - */ - public function register(): void - { - $this->app->bind( - ImportJobRepositoryInterface::class, - function (Application $app) { - /** @var ImportJobRepositoryInterface $repository */ - $repository = app(ImportJobRepository::class); - if ($app->auth->check()) { - $repository->setUser(auth()->user()); - } - - return $repository; - } - ); - } -} diff --git a/app/Repositories/Attachment/AttachmentRepository.php b/app/Repositories/Attachment/AttachmentRepository.php index 779de4f39b..19725336df 100644 --- a/app/Repositories/Attachment/AttachmentRepository.php +++ b/app/Repositories/Attachment/AttachmentRepository.php @@ -121,7 +121,7 @@ class AttachmentRepository implements AttachmentRepositoryInterface try { $unencryptedContent = Crypt::decrypt($encryptedContent); // verified } catch (DecryptException $e) { - Log::debug(sprintf('Could not decrypt: %e', $e->getMessage())); + //Log::debug(sprintf('Could not decrypt: %e', $e->getMessage())); $unencryptedContent = $encryptedContent; } } diff --git a/app/Repositories/ImportJob/ImportJobRepository.php b/app/Repositories/ImportJob/ImportJobRepository.php deleted file mode 100644 index 58b7547589..0000000000 --- a/app/Repositories/ImportJob/ImportJobRepository.php +++ /dev/null @@ -1,479 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Repositories\ImportJob; - -use Crypt; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Attachment; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\Tag; -use FireflyIII\User; -use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; -use Illuminate\Support\Str; -use Log; -use Storage; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Class ImportJobRepository. - * @codeCoverageIgnore - * @deprecated - * - */ -class ImportJobRepository implements ImportJobRepositoryInterface -{ - /** @var \Illuminate\Contracts\Filesystem\Filesystem */ - protected $uploadDisk; - /** @var int */ - private $maxUploadSize; - /** @var User */ - private $user; - - public function __construct() - { - $this->maxUploadSize = (int)config('firefly.maxUploadSize'); - $this->uploadDisk = Storage::disk('upload'); - - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Add message to job. - * - * @param ImportJob $job - * @param string $error - * - * @return ImportJob - */ - public function addErrorMessage(ImportJob $job, string $error): ImportJob - { - $errors = $job->errors; - $errors[] = $error; - $job->errors = $errors; - $job->save(); - - return $job; - } - - /** - * Append transactions to array instead of replacing them. - * - * @param ImportJob $job - * @param array $transactions - * - * @return ImportJob - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException - */ - public function appendTransactions(ImportJob $job, array $transactions): ImportJob - { - Log::debug(sprintf('Now in appendTransactions(%s)', $job->key)); - $existingTransactions = $this->getTransactions($job); - $new = array_merge($existingTransactions, $transactions); - Log::debug(sprintf('Old transaction count: %d', count($existingTransactions))); - Log::debug(sprintf('To be added transaction count: %d', count($transactions))); - Log::debug(sprintf('New count: %d', count($new))); - $this->setTransactions($job, $new); - - return $job; - } - - /** - * @param ImportJob $job - * - * @return int - */ - public function countTransactions(ImportJob $job): int - { - $info = $job->transactions ?? []; - if (isset($info['count'])) { - return (int)$info['count']; - } - - return 0; - } - - /** - * @param string $importProvider - * - * @return ImportJob - * - * @throws FireflyException - */ - public function create(string $importProvider): ImportJob - { - $count = 0; - $importProvider = strtolower($importProvider); - - while ($count < 30) { - $key = Str::random(12); - $existing = $this->findByKey($key); - if (null === $existing) { - $importJob = ImportJob::create( - [ - 'user_id' => $this->user->id, - 'tag_id' => null, - 'provider' => $importProvider, - 'file_type' => '', - 'key' => Str::random(12), - 'status' => 'new', - 'stage' => 'new', - 'configuration' => [], - 'extended_status' => [], - 'transactions' => [], - 'errors' => [], - ] - ); - - // breaks the loop: - return $importJob; - } - ++$count; - } - throw new FireflyException('Could not create an import job with a unique key after 30 tries.'); - } - - /** - * @param int $jobId - * - * @return ImportJob|null - */ - public function find(int $jobId): ?ImportJob - { - return $this->user->importJobs()->find($jobId); - } - - /** - * @param string $key - * - * @return ImportJob|null - */ - public function findByKey(string $key): ?ImportJob - { - /** @var ImportJob $result */ - $result = $this->user->importJobs()->where('key', $key)->first(['import_jobs.*']); - if (null === $result) { - return null; - } - - return $result; - } - - /** - * Return all import jobs. - * - * @return Collection - */ - public function get(): Collection - { - return $this->user->importJobs()->get(); - } - - /** - * Return all attachments for job. - * - * @param ImportJob $job - * - * @return Collection - */ - public function getAttachments(ImportJob $job): Collection - { - return $job->attachments()->get(); - } - - /** - * Return configuration of job. - * - * @param ImportJob $job - * - * @return array - */ - public function getConfiguration(ImportJob $job): array - { - return $job->configuration; - } - - /** - * Return extended status of job. - * - * @param ImportJob $job - * - * @return array - */ - public function getExtendedStatus(ImportJob $job): array - { - $status = $job->extended_status; - if (is_array($status)) { - return $status; - } - - return []; - } - - /** - * Return transactions from attachment. - * - * @param ImportJob $job - * - * @return array - * @throws \Illuminate\Contracts\Filesystem\FileNotFoundException - */ - public function getTransactions(ImportJob $job): array - { - // this will overwrite all transactions currently in the job. - $disk = Storage::disk('upload'); - $filename = sprintf('%s-%s.json', $job->created_at->format('Ymd'), $job->key); - $array = []; - if ($disk->exists($filename)) { - $json = $disk->get($filename); - $array = json_decode($json, true); - } - if (false === $array) { - $array = []; - } - - return $array; - } - - /** - * @param ImportJob $job - * @param array $configuration - * - * @return ImportJob - */ - public function setConfiguration(ImportJob $job, array $configuration): ImportJob - { - Log::debug('Updating configuration...'); - //Log::debug(sprintf('Incoming config for job "%s" is: ', $job->key), $configuration); - $currentConfig = $job->configuration; - $newConfig = array_merge($currentConfig, $configuration); - $job->configuration = $newConfig; - $job->save(); - - //Log::debug(sprintf('Set config of job "%s" to: ', $job->key), $newConfig); - - return $job; - } - - /** - * @param ImportJob $job - * @param string $stage - * - * @return ImportJob - */ - public function setStage(ImportJob $job, string $stage): ImportJob - { - $job->stage = $stage; - $job->save(); - - return $job; - } - - /** - * @param ImportJob $job - * @param string $status - * - * @return ImportJob - */ - public function setStatus(ImportJob $job, string $status): ImportJob - { - Log::debug(sprintf('Set status of job "%s" to "%s"', $job->key, $status)); - $job->status = $status; - $job->save(); - - return $job; - } - - /** - * @param ImportJob $job - * @param Tag $tag - * - * @return ImportJob - */ - public function setTag(ImportJob $job, Tag $tag): ImportJob - { - $job->tag()->associate($tag); - $job->save(); - - return $job; - } - - /** - * @param ImportJob $job - * @param array $transactions - * - * @return ImportJob - */ - public function setTransactions(ImportJob $job, array $transactions): ImportJob - { - // this will overwrite all transactions currently in the job. - $disk = Storage::disk('upload'); - $filename = sprintf('%s-%s.json', $job->created_at->format('Ymd'), $job->key); - $json = json_encode($transactions); - - // set count for easy access - $array = ['count' => count($transactions)]; - $job->transactions = $array; - $job->save(); - // store file. - $disk->put($filename, $json); - - return $job; - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - } - - /** - * Handle upload for job. - * - * @param ImportJob $job - * @param string $name - * @param string $fileName - * - * @return MessageBag - */ - public function storeCLIUpload(ImportJob $job, string $name, string $fileName): MessageBag - { - $messages = new MessageBag; - if (!file_exists($fileName)) { - $messages->add('notfound', sprintf('File not found: %s', $fileName)); - - return $messages; - } - - $count = $job->attachments()->get()->filter( - function (Attachment $att) use ($name) { - return $att->filename === $name; - } - )->count(); - - if ($count > 0) {// don't upload, but also don't complain about it. - Log::error(sprintf('Detected duplicate upload. Will ignore second "%s" file.', $name)); - - return new MessageBag; - } - $content = file_get_contents($fileName); - $attachment = new Attachment; // create Attachment object. - $attachment->user()->associate($job->user); - $attachment->attachable()->associate($job); - $attachment->md5 = substr(hash('sha256', $content), 0, 32); // limit due to DB. - $attachment->filename = $name; - $attachment->mime = 'plain/txt'; - $attachment->size = strlen($content); - $attachment->uploaded = false; - $attachment->save(); - - $this->uploadDisk->put($attachment->fileName(), $content); - $attachment->uploaded = true; // update attachment - $attachment->save(); - - return new MessageBag; - } - - /** - * Handle upload for job. - * - * @param ImportJob $job - * @param string $name - * @param UploadedFile $file - * - * @return MessageBag - * @throws FireflyException - */ - public function storeFileUpload(ImportJob $job, string $name, UploadedFile $file): MessageBag - { - $messages = new MessageBag; - if ($this->validSize($file)) { - $name = e($file->getClientOriginalName()); - $messages->add('size', (string)trans('validation.file_too_large', ['name' => $name])); - - return $messages; - } - $count = $job->attachments()->get()->filter( - function (Attachment $att) use ($name) { - return $att->filename === $name; - } - )->count(); - if ($count > 0) { // don't upload, but also don't complain about it. - Log::error(sprintf('Detected duplicate upload. Will ignore second "%s" file.', $name)); - - return new MessageBag; - } - - $attachment = new Attachment; // create Attachment object. - $attachment->user()->associate($job->user); - $attachment->attachable()->associate($job); - $attachment->md5 = md5_file($file->getRealPath()); - $attachment->filename = $name; - $attachment->mime = $file->getMimeType(); - $attachment->size = $file->getSize(); - $attachment->uploaded = false; - $attachment->save(); - $fileObject = $file->openFile(); - $fileObject->rewind(); - - - if (0 === $file->getSize()) { - throw new FireflyException('Cannot upload empty or non-existent file.'); - } - - $content = $fileObject->fread($file->getSize()); - $this->uploadDisk->put($attachment->fileName(), $content); - $attachment->uploaded = true; // update attachment - $attachment->save(); - - return new MessageBag; - } - - /** - * @codeCoverageIgnore - * - * @param UploadedFile $file - * - * @return bool - */ - protected function validSize(UploadedFile $file): bool - { - $size = $file->getSize(); - - return $size > $this->maxUploadSize; - } - - /** - * @param ImportJob $job - * - * @return int - */ - public function countByTag(ImportJob $job): int - { - return $job->tag->transactionJournals->count(); - } -} diff --git a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php b/app/Repositories/ImportJob/ImportJobRepositoryInterface.php deleted file mode 100644 index 4f585c78de..0000000000 --- a/app/Repositories/ImportJob/ImportJobRepositoryInterface.php +++ /dev/null @@ -1,207 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Repositories\ImportJob; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\Tag; -use FireflyIII\User; -use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; -use Symfony\Component\HttpFoundation\File\UploadedFile; - -/** - * Interface ImportJobRepositoryInterface. - * @codeCoverageIgnore - * @deprecated - */ -interface ImportJobRepositoryInterface -{ - /** - * Add message to job. - * - * @param ImportJob $job - * @param string $error - * - * @return ImportJob - */ - public function addErrorMessage(ImportJob $job, string $error): ImportJob; - - /** - * Append transactions to array instead of replacing them. - * - * @param ImportJob $job - * @param array $transactions - * - * @return ImportJob - */ - public function appendTransactions(ImportJob $job, array $transactions): ImportJob; - - /** - * @param ImportJob $job - * - * @return int - */ - public function countTransactions(ImportJob $job): int; - - /** - * @param ImportJob $job - * - * @return int - */ - public function countByTag(ImportJob $job): int; - - /** - * @param string $importProvider - * - * @return ImportJob - */ - public function create(string $importProvider): ImportJob; - - /** - * @param int $jobId - * - * @return ImportJob|null - */ - public function find(int $jobId): ?ImportJob; - - /** - * @param string $key - * - * @return ImportJob|null - */ - public function findByKey(string $key): ?ImportJob; - - /** - * Return all import jobs. - * - * @return Collection - */ - public function get(): Collection; - - /** - * Return all attachments for job. - * - * @param ImportJob $job - * - * @return Collection - */ - public function getAttachments(ImportJob $job): Collection; - - /** - * Return configuration of job. - * - * @param ImportJob $job - * - * @return array - */ - public function getConfiguration(ImportJob $job): array; - - /** - * Return extended status of job. - * - * @param ImportJob $job - * - * @return array - */ - public function getExtendedStatus(ImportJob $job): array; - - /** - * Return transactions from attachment. - * - * @param ImportJob $job - * - * @return array - */ - public function getTransactions(ImportJob $job): array; - - /** - * @param ImportJob $job - * @param array $configuration - * - * @return ImportJob - */ - public function setConfiguration(ImportJob $job, array $configuration): ImportJob; - - /** - * @param ImportJob $job - * @param string $stage - * - * @return ImportJob - */ - public function setStage(ImportJob $job, string $stage): ImportJob; - - /** - * @param ImportJob $job - * @param string $status - * - * @return ImportJob - */ - public function setStatus(ImportJob $job, string $status): ImportJob; - - /** - * @param ImportJob $job - * @param Tag $tag - * - * @return ImportJob - */ - public function setTag(ImportJob $job, Tag $tag): ImportJob; - - /** - * @param ImportJob $job - * @param array $transactions - * - * @return ImportJob - */ - public function setTransactions(ImportJob $job, array $transactions): ImportJob; - - /** - * @param User $user - */ - public function setUser(User $user); - - /** - * Store file. - * - * @param ImportJob $job - * @param string $name - * @param string $fileName - * - * @return MessageBag - */ - public function storeCLIUpload(ImportJob $job, string $name, string $fileName): MessageBag; - - /** - * Handle upload for job. - * - * @param ImportJob $job - * @param string $name - * @param UploadedFile $file - * - * @return MessageBag - * @throws FireflyException - */ - public function storeFileUpload(ImportJob $job, string $name, UploadedFile $file): MessageBag; - - -} diff --git a/app/Repositories/Journal/JournalRepository.php b/app/Repositories/Journal/JournalRepository.php index d25545750b..118f2aeace 100644 --- a/app/Repositories/Journal/JournalRepository.php +++ b/app/Repositories/Journal/JournalRepository.php @@ -98,32 +98,6 @@ class JournalRepository implements JournalRepositoryInterface $service->destroy($journal); } - /** - * Find a journal by its hash. - * - * @param string $hash - * - * @return TransactionJournalMeta|null - */ - public function findByHash(string $hash): ?TransactionJournalMeta - { - $jsonEncode = json_encode($hash); - $hashOfHash = hash('sha256', $jsonEncode); - Log::debug(sprintf('JSON encoded hash is: %s', $jsonEncode)); - Log::debug(sprintf('Hash of hash is: %s', $hashOfHash)); - - $result = TransactionJournalMeta::withTrashed() - ->leftJoin('transaction_journals', 'transaction_journals.id', '=', 'journal_meta.transaction_journal_id') - ->where('hash', $hashOfHash) - ->where('name', 'import_hash_v2') - ->first(['journal_meta.*']); - if (null === $result) { - Log::debug('Result is null'); - } - - return $result; - } - /** * Find a specific journal. * diff --git a/app/Repositories/Journal/JournalRepositoryInterface.php b/app/Repositories/Journal/JournalRepositoryInterface.php index e188c69002..6c34c92337 100644 --- a/app/Repositories/Journal/JournalRepositoryInterface.php +++ b/app/Repositories/Journal/JournalRepositoryInterface.php @@ -67,18 +67,6 @@ interface JournalRepositoryInterface */ public function destroyJournal(TransactionJournal $journal): void; - - /** - * TODO move to import repository. - * - * Find a journal by its hash. - * - * @param string $hash - * - * @return TransactionJournalMeta|null - */ - public function findByHash(string $hash): ?TransactionJournalMeta; - /** * TODO Refactor to "find". * Find a specific journal. diff --git a/app/Repositories/ObjectGroup/CreatesObjectGroups.php b/app/Repositories/ObjectGroup/CreatesObjectGroups.php new file mode 100644 index 0000000000..3bdc83bf1f --- /dev/null +++ b/app/Repositories/ObjectGroup/CreatesObjectGroups.php @@ -0,0 +1,74 @@ +user->objectGroups()->where('title', $title)->first(); + } + + /** + * @param int $groupId + * + * @return ObjectGroup|null + */ + protected function findObjectGroupById(int $groupId): ?ObjectGroup + { + return $this->user->objectGroups()->where('id', $groupId)->first(); + } + + /** + * @param User $user + * @param string $title + * + * @return ObjectGroup|null + */ + protected function findOrCreateObjectGroup(string $title): ?ObjectGroup + { + $group = null; + $maxOrder = $this->getObjectGroupMaxOrder(); + if (!$this->hasObjectGroup($title)) { + return ObjectGroup::create( + [ + 'user_id' => $this->user->id, + 'title' => $title, + 'order' => $maxOrder + 1, + ] + ); + } + + return $this->findObjectGroup($title); + } + + /** + * @return int + */ + protected function getObjectGroupMaxOrder(): int + { + return (int) $this->user->objectGroups()->max('order'); + } + + /** + * @param string $title + * + * @return bool + */ + protected function hasObjectGroup(string $title): bool + { + return 1 === $this->user->objectGroups()->where('title', $title)->count(); + } +} diff --git a/app/Repositories/ObjectGroup/ObjectGroupRepository.php b/app/Repositories/ObjectGroup/ObjectGroupRepository.php new file mode 100644 index 0000000000..17e68e492f --- /dev/null +++ b/app/Repositories/ObjectGroup/ObjectGroupRepository.php @@ -0,0 +1,151 @@ +user->objectGroups()->orderBy('order', 'ASC')->orderBy('title', 'ASC')->get(); + } + + /** + * @param string $query + * + * @return Collection + */ + public function search(string $query): Collection + { + $dbQuery = $this->user->objectGroups()->orderBy('order', 'ASC')->orderBy('title', 'ASC'); + if ('' !== $query) { + // split query on spaces just in case: + $parts = explode(' ', $query); + foreach ($parts as $part) { + $search = sprintf('%%%s%%', $part); + $dbQuery->where('title', 'LIKE', $search); + } + + } + + return $dbQuery->get(['object_groups.*']); + } + + /** + * @inheritDoc + */ + public function deleteEmpty(): void + { + $all = $this->get(); + /** @var ObjectGroup $group */ + foreach ($all as $group) { + $count = DB::table('object_groupables')->where('object_groupables.object_group_id', $group->id)->count(); + if (0 === $count) { + $group->delete(); + } + } + } + + /** + * @inheritDoc + */ + public function sort(): void + { + $all = $this->get(); + /** + * @var int $index + * @var ObjectGroup $group + */ + foreach ($all as $index => $group) { + $group->order = $index + 1; + $group->save(); + } + } + + /** + * @inheritDoc + */ + public function setOrder(ObjectGroup $objectGroup, int $order): ObjectGroup + { + $order = 0 === $order ? 1 : $order; + $objectGroup->order = $order; + $objectGroup->save(); + + Log::debug(sprintf('Objectgroup #%d order is now %d', $objectGroup->id, $order)); + + return $objectGroup; + } + + /** + * @inheritDoc + */ + public function update(ObjectGroup $objectGroup, array $data): ObjectGroup + { + $objectGroup->title = $data['title']; + + if (isset($data['order'])) { + $order = 0 === $data['order'] ? 1 : $data['order']; + $objectGroup->order = $order; + } + + $objectGroup->save(); + + return $objectGroup; + } + + /** + * @inheritDoc + */ + public function destroy(ObjectGroup $objectGroup): void + { + $list = $objectGroup->piggyBanks; + /** @var PiggyBank $piggy */ + foreach($list as $piggy) { + $piggy->objectGroups()->sync([]); + $piggy->save(); + } + $objectGroup->delete(); + } + + /** + * @param User $user + */ + public function setUser(User $user): void + { + $this->user = $user; + } + + /** + * @inheritDoc + */ + public function getPiggyBanks(ObjectGroup $objectGroup): Collection + { + return $objectGroup->piggyBanks; + } +} diff --git a/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php b/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php new file mode 100644 index 0000000000..4d190c007b --- /dev/null +++ b/app/Repositories/ObjectGroup/ObjectGroupRepositoryInterface.php @@ -0,0 +1,64 @@ +deleteEmptyObjectGroups(); + $this->sortObjectGroups(); + } + + /** + * + */ + private function deleteEmptyObjectGroups(): void + { + $repository = app(ObjectGroupRepositoryInterface::class); + $repository->deleteEmpty(); + } + + /** + * + */ + private function sortObjectGroups(): void + { + $repository = app(ObjectGroupRepositoryInterface::class); + $repository->sort(); + } +} diff --git a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php index 7b72fcf652..4528dba729 100644 --- a/app/Repositories/PiggyBank/ModifiesPiggyBanks.php +++ b/app/Repositories/PiggyBank/ModifiesPiggyBanks.php @@ -31,6 +31,7 @@ use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBankEvent; use FireflyIII\Models\PiggyBankRepetition; use FireflyIII\Models\TransactionJournal; +use FireflyIII\Repositories\ObjectGroup\CreatesObjectGroups; use Illuminate\Database\QueryException; use Log; @@ -39,7 +40,7 @@ use Log; */ trait ModifiesPiggyBanks { - + use CreatesObjectGroups; /** * @param PiggyBank $piggyBank * @param string $amount @@ -62,6 +63,17 @@ trait ModifiesPiggyBanks return true; } + /** + * @inheritDoc + */ + public function removeObjectGroup(PiggyBank $piggyBank): PiggyBank + { + $piggyBank->objectGroups()->sync([]); + + return $piggyBank; + } + + /** * @param PiggyBankRepetition $repetition * @param string $amount @@ -180,6 +192,7 @@ trait ModifiesPiggyBanks */ public function destroy(PiggyBank $piggyBank): bool { + $piggyBank->objectGroups()->sync([]); $piggyBank->delete(); return true; @@ -248,6 +261,22 @@ trait ModifiesPiggyBanks return true; } + + /** + * @inheritDoc + */ + public function setObjectGroup(PiggyBank $piggyBank, string $objectGroupTitle): PiggyBank + { + $objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle); + if (null !== $objectGroup) { + $piggyBank->objectGroups()->sync([$objectGroup->id]); + } + + return $piggyBank; + + } + + /** * @param array $data * @@ -269,11 +298,29 @@ trait ModifiesPiggyBanks // repetition is auto created. $repetition = $this->getRepetition($piggyBank); - if (null !== $repetition && isset($data['current_amount'])) { + if (null !== $repetition && isset($data['current_amount']) && '' !== $data['current_amount']) { $repetition->currentamount = $data['current_amount']; $repetition->save(); } + $objectGroupTitle = $data['object_group'] ?? ''; + if ('' !== $objectGroupTitle) { + $objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle); + if (null !== $objectGroup) { + $piggyBank->objectGroups()->sync([$objectGroup->id]); + $piggyBank->save(); + } + } + // try also with ID: + $objectGroupId = (int) ($data['object_group_id'] ?? 0); + if (0 !== $objectGroupId) { + $objectGroup = $this->findObjectGroupById($objectGroupId); + if (null !== $objectGroup) { + $piggyBank->objectGroups()->sync([$objectGroup->id]); + $piggyBank->save(); + } + } + return $piggyBank; } @@ -313,6 +360,15 @@ trait ModifiesPiggyBanks $repetition->save(); } + $objectGroupTitle = $data['object_group'] ?? ''; + if ('' !== $objectGroupTitle) { + $objectGroup = $this->findOrCreateObjectGroup($objectGroupTitle); + if (null !== $objectGroup) { + $piggyBank->objectGroups()->sync([$objectGroup->id]); + $piggyBank->save(); + } + } + return $piggyBank; } diff --git a/app/Repositories/PiggyBank/PiggyBankRepository.php b/app/Repositories/PiggyBank/PiggyBankRepository.php index 3be16b5c9e..7db78aa20d 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepository.php +++ b/app/Repositories/PiggyBank/PiggyBankRepository.php @@ -265,7 +265,7 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface */ public function getPiggyBanks(): Collection { - return $this->user->piggyBanks()->with(['account'])->orderBy('order', 'ASC')->get(); + return $this->user->piggyBanks()->with(['account', 'objectGroups'])->orderBy('order', 'ASC')->get(); } @@ -393,4 +393,6 @@ class PiggyBankRepository implements PiggyBankRepositoryInterface return $set; } + + } diff --git a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php index aa07fdb025..bc4257f628 100644 --- a/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php +++ b/app/Repositories/PiggyBank/PiggyBankRepositoryInterface.php @@ -36,6 +36,21 @@ use Illuminate\Support\Collection; */ interface PiggyBankRepositoryInterface { + /** + * @param PiggyBank $piggyBank + * @param string $objectGroupTitle + * + * @return PiggyBank + */ + public function setObjectGroup(PiggyBank $piggyBank, string $objectGroupTitle): PiggyBank; + + /** + * @param PiggyBank $piggyBank + * + * @return PiggyBank + */ + public function removeObjectGroup(PiggyBank $piggyBank): PiggyBank; + /** * @param PiggyBank $piggyBank * @param string $amount diff --git a/app/Repositories/Rule/RuleRepository.php b/app/Repositories/Rule/RuleRepository.php index c9b16dbe8a..503da28791 100644 --- a/app/Repositories/Rule/RuleRepository.php +++ b/app/Repositories/Rule/RuleRepository.php @@ -112,26 +112,6 @@ class RuleRepository implements RuleRepositoryInterface return $this->user->ruleGroups()->first(); } - /** - * Get the rules for a user tailored to the import process. - * - * @return Collection - */ - public function getForImport(): Collection - { - return Rule::distinct() - ->where('rules.user_id', $this->user->id) - ->leftJoin('rule_groups', 'rule_groups.id', '=', 'rules.rule_group_id') - ->leftJoin('rule_triggers', 'rules.id', '=', 'rule_triggers.rule_id') - ->where('rule_groups.active', 1) - ->where('rule_triggers.trigger_type', 'user_action') - ->where('rule_triggers.trigger_value', 'store-journal') - ->where('rules.active', 1) - ->orderBy('rule_groups.order', 'ASC') - ->orderBy('rules.order', 'ASC') - ->get(['rules.*', 'rule_groups.order']); - } - /** * @param RuleGroup $ruleGroup * diff --git a/app/Repositories/Rule/RuleRepositoryInterface.php b/app/Repositories/Rule/RuleRepositoryInterface.php index a979201e34..dc8e96b9a1 100644 --- a/app/Repositories/Rule/RuleRepositoryInterface.php +++ b/app/Repositories/Rule/RuleRepositoryInterface.php @@ -72,13 +72,6 @@ interface RuleRepositoryInterface */ public function getFirstRuleGroup(): RuleGroup; - /** - * Get the rules for a user tailored to the import process. - * - * @return Collection - */ - public function getForImport(): Collection; - /** * @param RuleGroup $ruleGroup * diff --git a/app/Repositories/TransactionGroup/TransactionGroupRepository.php b/app/Repositories/TransactionGroup/TransactionGroupRepository.php index 98c489b8b7..962b4b8f5f 100644 --- a/app/Repositories/TransactionGroup/TransactionGroupRepository.php +++ b/app/Repositories/TransactionGroup/TransactionGroupRepository.php @@ -208,7 +208,7 @@ class TransactionGroupRepository implements TransactionGroupRepositoryInterface $return = []; foreach ($query as $row) { - $return[$row->name] = new Carbon(json_decode($row->data)); + $return[$row->name] = new Carbon(json_decode($row->data, true, 512, JSON_THROW_ON_ERROR)); } return new NullArrayObject($return); diff --git a/app/Repositories/User/UserRepository.php b/app/Repositories/User/UserRepository.php index 8bee7968c0..0182e82bde 100644 --- a/app/Repositories/User/UserRepository.php +++ b/app/Repositories/User/UserRepository.php @@ -261,8 +261,6 @@ class UserRepository implements UserRepositoryInterface ->where('amount', '>', 0) ->whereNull('budgets.deleted_at') ->where('budgets.user_id', $user->id)->get(['budget_limits.budget_id'])->count(); - $return['import_jobs'] = $user->importJobs()->count(); - $return['import_jobs_success'] = $user->importJobs()->where('status', 'finished')->count(); $return['rule_groups'] = $user->ruleGroups()->count(); $return['rules'] = $user->rules()->count(); $return['tags'] = $user->tags()->count(); diff --git a/app/Rules/IsValidAttachmentModel.php b/app/Rules/IsValidAttachmentModel.php index 441f78b0f9..4dc3dbcf92 100644 --- a/app/Rules/IsValidAttachmentModel.php +++ b/app/Rules/IsValidAttachmentModel.php @@ -28,7 +28,6 @@ use FireflyIII\Models\Account; use FireflyIII\Models\Bill; use FireflyIII\Models\Budget; use FireflyIII\Models\Category; -use FireflyIII\Models\ImportJob; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Tag; use FireflyIII\Models\Transaction; @@ -37,7 +36,6 @@ use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Bill\BillRepositoryInterface; use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; use FireflyIII\Repositories\Category\CategoryRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Repositories\Journal\JournalAPIRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Repositories\PiggyBank\PiggyBankRepositoryInterface; @@ -94,7 +92,6 @@ class IsValidAttachmentModel implements Rule Bill::class => 'validateBill', Budget::class => 'validateBudget', Category::class => 'validateCategory', - ImportJob::class => 'validateImportJob', PiggyBank::class => 'validatePiggyBank', Tag::class => 'validateTag', Transaction::class => 'validateTransaction', @@ -207,20 +204,6 @@ class IsValidAttachmentModel implements Rule return null !== $repository->findTransaction((int) $value); } - /** - * @param int $value - * - * @return bool - */ - private function validateImportJob(int $value): bool - { - /** @var ImportJobRepositoryInterface $repository */ - $repository = app(ImportJobRepositoryInterface::class); - $repository->setUser(auth()->user()); - - return null !== $repository->find($value); - } - /** * @param int $value * diff --git a/app/Services/Bunq/ApiContext.php b/app/Services/Bunq/ApiContext.php deleted file mode 100644 index 679b5b0b46..0000000000 --- a/app/Services/Bunq/ApiContext.php +++ /dev/null @@ -1,96 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Bunq; - -use bunq\Context\ApiContext as BunqApiContext; -use bunq\Context\BunqContext; -use bunq\Util\BunqEnumApiEnvironmentType; -use Exception; -use FireflyIII\Exceptions\FireflyException; -use Log; -use Tests\Object\FakeApiContext; - -/** - * Special class to hide away bunq's static initialisation methods. - * - * Class ApiContext - * - * @codeCoverageIgnore - * @deprecated - */ -class ApiContext -{ - - /** - * @param BunqEnumApiEnvironmentType $environmentType - * @param string $apiKey - * @param string $description - * @param array $permittedIps - * @param string|null $proxyUrl - * - * @return BunqApiContext|FakeApiContext - * - *@throws FireflyException - */ - public function create(BunqEnumApiEnvironmentType $environmentType, string $apiKey, string $description, array $permittedIps, string $proxyUrl = null - ) { - $permittedIps = $permittedIps ?? []; - try { - $context = BunqApiContext::create($environmentType, $apiKey, $description, $permittedIps, $proxyUrl); - } catch (Exception $e) { - $message = $e->getMessage(); - Log::error($message); - Log::error($e->getTraceAsString()); - - if (stripos($message, 'Generating a new private key failed')) { - $message = 'Could not generate key-material. Please make sure OpenSSL is installed and configured: http://bit.ly/FF3-openSSL'; - } - throw new FireflyException($message); - } - - return $context; - } - - /** - * @throws FireflyException - * - * @param string $jsonString - */ - public function fromJson(string $jsonString): void - { - try { - $apiContext = BunqApiContext::fromJson($jsonString); - BunqContext::loadApiContext($apiContext); - } catch (Exception $e) { - $message = $e->getMessage(); - Log::error($message); - Log::error($e->getTraceAsString()); - - if (stripos($message, 'Generating a new private key failed')) { - $message = 'Could not generate key-material. Please make sure OpenSSL is installed and configured: http://bit.ly/FF3-openSSL'; - } - throw new FireflyException($message); - } - } -} diff --git a/app/Services/Bunq/MonetaryAccount.php b/app/Services/Bunq/MonetaryAccount.php deleted file mode 100644 index 27cc131567..0000000000 --- a/app/Services/Bunq/MonetaryAccount.php +++ /dev/null @@ -1,59 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Bunq; - - -use bunq\Model\Generated\Endpoint\BunqResponseMonetaryAccountList; -use bunq\Model\Generated\Endpoint\MonetaryAccount as BunqMonetaryAccount; -use Exception; -use FireflyIII\Exceptions\FireflyException; - -/** - * Class MonetaryAccount - * @codeCoverageIgnore - * @deprecated - */ -class MonetaryAccount -{ - /** - * @param array $params - * @param array $customHeaders - * - * @return BunqResponseMonetaryAccountList - * @throws FireflyException - */ - public function listing(array $params = null, array $customHeaders = null): BunqResponseMonetaryAccountList - { - $params = $params ?? []; - $customHeaders = $customHeaders ?? []; - try { - $result = BunqMonetaryAccount::listing($params, $customHeaders); - } catch (Exception $e) { - throw new FireflyException($e->getMessage()); - } - - return $result; - } - -} diff --git a/app/Services/Bunq/Payment.php b/app/Services/Bunq/Payment.php deleted file mode 100644 index 1ff540e7e9..0000000000 --- a/app/Services/Bunq/Payment.php +++ /dev/null @@ -1,63 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Bunq; - - -use bunq\Model\Generated\Endpoint\BunqResponsePaymentList; -use bunq\Model\Generated\Endpoint\Payment as BunqPayment; -use Exception; -use FireflyIII\Exceptions\FireflyException; - -/** - * Class Payment - * @codeCoverageIgnore - * @deprecated - */ -class Payment -{ - /** - * @param int|null $monetaryAccountId - * @param array|null $params - * @param array|null $customHeaders - * - * @throws FireflyException - * @return BunqResponsePaymentList - */ - public function listing(int $monetaryAccountId = null, array $params = null, array $customHeaders = null): BunqResponsePaymentList - { - $monetaryAccountId = $monetaryAccountId ?? 0; - $params = $params ?? []; - $customHeaders = $customHeaders ?? []; - try { - $result = BunqPayment::listing($monetaryAccountId, $params, $customHeaders); - } catch (Exception $e) { - throw new FireflyException($e->getMessage()); - } - - return $result; - - - } - -} diff --git a/app/Services/Github/Object/GithubObject.php b/app/Services/Github/Object/GithubObject.php deleted file mode 100644 index ce2040cb16..0000000000 --- a/app/Services/Github/Object/GithubObject.php +++ /dev/null @@ -1,31 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Services\Github\Object; - -/** - * @codeCoverageIgnore - * Class GithubObject - */ -class GithubObject -{ -} diff --git a/app/Services/Github/Object/Release.php b/app/Services/Github/Object/Release.php deleted file mode 100644 index f7c2449ff5..0000000000 --- a/app/Services/Github/Object/Release.php +++ /dev/null @@ -1,94 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Github\Object; - -use Carbon\Carbon; - - -/** - * - * Class Release - * - * @SuppressWarnings(PHPMD.ShortVariable) - * - * @codeCoverageIgnore - */ -class Release extends GithubObject -{ - /** @var string */ - private $content; - /** @var string */ - private $id; - /** @var string */ - private $title; - /** @var Carbon */ - private $updated; - - /** - * Release constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->id = $data['id']; - $this->updated = new Carbon($data['updated']); - $this->title = $data['title']; - $this->content = $data['content']; - } - - /** - * @return string - */ - public function getContent(): string - { - return $this->content; - } - - /** - * @return string - */ - public function getId(): string - { - return $this->id; - } - - /** - * @return string - */ - public function getTitle(): string - { - return $this->title; - } - - /** - * @return Carbon - */ - public function getUpdated(): Carbon - { - return $this->updated; - } - - -} diff --git a/app/Services/Github/Request/GithubRequest.php b/app/Services/Github/Request/GithubRequest.php deleted file mode 100644 index 05424da0c3..0000000000 --- a/app/Services/Github/Request/GithubRequest.php +++ /dev/null @@ -1,34 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Github\Request; - -/** - * Interface GithubRequest - * @deprecated - */ -interface GithubRequest -{ - public function call(): void; - -} diff --git a/app/Services/Github/Request/UpdateRequest.php b/app/Services/Github/Request/UpdateRequest.php deleted file mode 100644 index 1366cb05c6..0000000000 --- a/app/Services/Github/Request/UpdateRequest.php +++ /dev/null @@ -1,96 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Github\Request; - -use Exception; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Services\Github\Object\Release; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\GuzzleException; -use Log; -use RuntimeException; -use SimpleXMLElement; - -/** - * Class UpdateRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class UpdateRequest implements GithubRequest -{ - /** @var array */ - private $releases = []; - - /** - * - * @throws FireflyException - */ - public function call(): void - { - $uri = 'https://github.com/firefly-iii/firefly-iii/releases.atom'; - Log::debug(sprintf('Going to call %s', $uri)); - try { - $client = new Client(); - $res = $client->request('GET', $uri); - } catch (GuzzleException|Exception $e) { - throw new FireflyException(sprintf('Response error from Github: %s', $e->getMessage())); - } - - if (200 !== $res->getStatusCode()) { - throw new FireflyException(sprintf('Returned code %d.', $res->getStatusCode())); - } - try { - $releaseXml = new SimpleXMLElement($res->getBody()->getContents(), LIBXML_NOCDATA); - } catch (RuntimeException $e) { - Log::error(sprintf('Could not get body from github updat result: %s', $e->getMessage())); - throw new FireflyException(sprintf('Could not get body from github updat result: %s', $e->getMessage())); - } - - //fetch the products for each category - if (isset($releaseXml->entry)) { - Log::debug(sprintf('Count of entries is: %d', count($releaseXml->entry))); - foreach ($releaseXml->entry as $entry) { - $array = [ - 'id' => (string)$entry->id, - 'updated' => (string)$entry->updated, - 'title' => (string)$entry->title, - 'content' => (string)$entry->content, - ]; - Log::debug(sprintf('Found version %s', $entry->title)); - $this->releases[] = new Release($array); - } - } - } - - /** - * @return array - */ - public function getReleases(): array - { - return $this->releases; - } - - -} diff --git a/app/Services/IP/IPRetrievalInterface.php b/app/Services/IP/IPRetrievalInterface.php deleted file mode 100644 index d8d8899081..0000000000 --- a/app/Services/IP/IPRetrievalInterface.php +++ /dev/null @@ -1,40 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\IP; - -/** - * Interface IPRetrievalInterface - * @codeCoverageIgnore - * @deprecated - */ -interface IPRetrievalInterface -{ - - /** - * Returns the user's IP address. - * - * @return null|string - */ - public function getIP(): ?string; -} diff --git a/app/Services/IP/IpifyOrg.php b/app/Services/IP/IpifyOrg.php deleted file mode 100644 index 1bfb54e1f0..0000000000 --- a/app/Services/IP/IpifyOrg.php +++ /dev/null @@ -1,81 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\IP; - -use Exception; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\GuzzleException; -use Log; -use RuntimeException; - -/** - * Class IpifyOrg - * - * @codeCoverageIgnore - * @deprecated - */ -class IpifyOrg implements IPRetrievalInterface -{ - /** - * Constructor. - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Returns the user's IP address. - * - * @noinspection MultipleReturnStatementsInspection - * @return null|string - */ - public function getIP(): ?string - { - try { - $client = new Client; - $res = $client->request('GET', 'https://api.ipify.org'); - } catch (GuzzleException|Exception $e) { - Log::warning(sprintf('The ipify.org service could not retrieve external IP: %s', $e->getMessage())); - Log::warning($e->getTraceAsString()); - - return null; - } - if (200 !== $res->getStatusCode()) { - Log::warning(sprintf('Could not retrieve external IP: %d', $res->getStatusCode())); - - return null; - } - try { - $body = (string)$res->getBody()->getContents(); - } catch (RuntimeException $e) { - Log::error(sprintf('Could not get body from ipify.org result: %s', $e->getMessage())); - $body = null; - } - - return $body; - } -} diff --git a/app/Services/Spectre/Exception/DuplicatedCustomerException.php b/app/Services/Spectre/Exception/DuplicatedCustomerException.php deleted file mode 100644 index 8beb4cc17d..0000000000 --- a/app/Services/Spectre/Exception/DuplicatedCustomerException.php +++ /dev/null @@ -1,34 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Exception; - -/** - * @codeCoverageIgnore - * Class DuplicatedCustomerException - * @deprecated - */ -class DuplicatedCustomerException extends SpectreException -{ - -} diff --git a/app/Services/Spectre/Exception/SpectreException.php b/app/Services/Spectre/Exception/SpectreException.php deleted file mode 100644 index 73e0e22c81..0000000000 --- a/app/Services/Spectre/Exception/SpectreException.php +++ /dev/null @@ -1,36 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Exception; - -use Exception; - -/** - * @codeCoverageIgnore - * Class SpectreException - * @deprecated - */ -class SpectreException extends Exception -{ - -} diff --git a/app/Services/Spectre/Exception/WrongRequestFormatException.php b/app/Services/Spectre/Exception/WrongRequestFormatException.php deleted file mode 100644 index 5dce219a97..0000000000 --- a/app/Services/Spectre/Exception/WrongRequestFormatException.php +++ /dev/null @@ -1,34 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Exception; - -/** - * @codeCoverageIgnore - * Class WrongRequestFormatException - * @deprecated - */ -class WrongRequestFormatException extends SpectreException -{ - -} diff --git a/app/Services/Spectre/Object/Account.php b/app/Services/Spectre/Object/Account.php deleted file mode 100644 index 2da7f1fd11..0000000000 --- a/app/Services/Spectre/Object/Account.php +++ /dev/null @@ -1,145 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -use Carbon\Carbon; - -/** - * Class Account - * - * @codeCoverageIgnore - * @SuppressWarnings(PHPMD.ShortVariable) - * @deprecated - */ -class Account extends SpectreObject -{ - /** @var float */ - private $balance; - /** @var Carbon */ - private $createdAt; - /** @var string */ - private $currencyCode; - /** @var array */ - private $extra = []; - /** @var int */ - private $id; - /** @var int */ - private $loginId; - /** @var string */ - private $name; - /** @var string */ - private $nature; - /** @var Carbon */ - private $updatedAt; - - /** - * Account constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->id = (int)$data['id']; - $this->loginId = $data['login_id']; - $this->currencyCode = $data['currency_code']; - $this->balance = $data['balance']; - $this->name = $data['name']; - $this->nature = $data['nature']; - $this->createdAt = new Carbon($data['created_at']); - $this->updatedAt = new Carbon($data['updated_at']); - $extraArray = is_array($data['extra']) ? $data['extra'] : []; - foreach ($extraArray as $key => $value) { - $this->extra[$key] = $value; - } - } - - /** - * @return float - */ - public function getBalance(): float - { - return $this->balance; - } - - /** - * @return string - */ - public function getCurrencyCode(): string - { - return $this->currencyCode; - } - - /** - * @return array - */ - public function getExtra(): array - { - return $this->extra; - } - - /** - * @return int - */ - public function getId(): int - { - return $this->id; - } - - /** - * @return string - */ - public function getName(): string - { - return $this->name; - } - - /** - * @return string - */ - public function getNature(): string - { - return $this->nature; - } - - /** - * @return array - */ - public function toArray(): array - { - $array = [ - 'balance' => $this->balance, - 'created_at' => $this->createdAt->toIso8601String(), - 'currency_code' => $this->currencyCode, - 'extra' => $this->extra, - 'id' => $this->id, - 'login_id' => $this->loginId, - 'name' => $this->name, - 'nature' => $this->nature, - 'updated_at' => $this->updatedAt->toIso8601String(), - ]; - - return $array; - } - -} diff --git a/app/Services/Spectre/Object/Attempt.php b/app/Services/Spectre/Object/Attempt.php deleted file mode 100644 index 434ecfbbd8..0000000000 --- a/app/Services/Spectre/Object/Attempt.php +++ /dev/null @@ -1,214 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -use Carbon\Carbon; - -/** - * - * Class Attempt - * - * @codeCoverageIgnore - * @SuppressWarnings(PHPMD.ShortVariable) - * @SuppressWarnings(PHPMD.TooManyFields) - * @deprecated - */ -class Attempt extends SpectreObject -{ - /** @var string */ - private $apiMode; - /** @var int */ - private $apiVersion; - /** @var bool */ - private $automaticFetch; - /** @var bool */ - private $categorize; - /** @var Carbon */ - private $consentGivenAt; - /** @var array */ - private $consentTypes; - /** @var Carbon */ - private $createdAt; - /** @var array */ - private $customFields; - /** @var bool */ - private $dailyRefresh; - /** @var string */ - private $deviceType; - /** @var array */ - private $excludeAccounts; - /** @var Carbon */ - private $failAt; - /** @var string */ - private $failErrorClass; - /** @var string */ - private $failMessage; - /** @var array */ - private $fetchScopes; - /** @var bool */ - private $finished; - /** @var bool */ - private $finishedRecent; - /** @var Carbon */ - private $fromDate; - /** @var int */ - private $id; - /** @var bool */ - private $interactive; - /** @var string */ - private $locale; - /** @var bool */ - private $partial; - /** @var string */ - private $remoteIp; - /** @var bool */ - private $showConsentInformation; - /** @var array */ - private $stages; - /** @var bool */ - private $storeCredentials; - /** @var Carbon */ - private $successAt; - /** @var Carbon */ - private $toDate; - /** @var Carbon */ - private $updatedAt; // undocumented - /** @var string */ - private $userAgent; - - /** - * Attempt constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->apiMode = $data['api_mode']; - $this->apiVersion = $data['api_version']; - $this->automaticFetch = $data['automatic_fetch']; - $this->categorize = $data['categorize']; - $this->createdAt = new Carbon($data['created_at']); - $this->consentGivenAt = new Carbon($data['consent_given_at']); - $this->consentTypes = $data['consent_types']; - $this->customFields = $data['custom_fields']; - $this->dailyRefresh = $data['daily_refresh']; - $this->deviceType = $data['device_type']; - $this->userAgent = $data['user_agent'] ?? ''; - $this->remoteIp = $data['remote_ip']; - $this->excludeAccounts = $data['exclude_accounts']; - $this->failAt = new Carbon($data['fail_at']); - $this->failErrorClass = $data['fail_error_class']; - $this->failMessage = $data['fail_message']; - $this->fetchScopes = $data['fetch_scopes']; - $this->finished = $data['finished']; - $this->finishedRecent = $data['finished_recent']; - $this->fromDate = new Carbon($data['from_date']); - $this->id = $data['id']; - $this->interactive = $data['interactive']; - $this->locale = $data['locale']; - $this->partial = $data['partial']; - $this->showConsentInformation = $data['show_consent_confirmation']; - $this->stages = $data['stages'] ?? []; - $this->storeCredentials = $data['store_credentials']; - $this->successAt = new Carbon($data['success_at']); - $this->toDate = new Carbon($data['to_date']); - $this->updatedAt = new Carbon($data['updated_at']); - - } - - /** - * @return Carbon - */ - public function getCreatedAt(): Carbon - { - return $this->createdAt; - } - - /** - * @return Carbon - */ - public function getFailAt(): Carbon - { - return $this->failAt; - } - - /** - * @return null|string - */ - public function getFailErrorClass(): ?string - { - return $this->failErrorClass; - } - - /** - * @return null|string - */ - public function getFailMessage(): ?string - { - return $this->failMessage; - } - - /** - * @return array - */ - public function toArray(): array - { - $array = [ - 'api_mode' => $this->apiMode, - 'api_version' => $this->apiVersion, - 'automatic_fetch' => $this->automaticFetch, - 'categorize' => $this->categorize, - 'created_at' => $this->createdAt->toIso8601String(), - 'consent_given_at' => $this->consentGivenAt->toIso8601String(), - 'consent_types' => $this->consentTypes, - 'custom_fields' => $this->customFields, - 'daily_refresh' => $this->dailyRefresh, - 'device_type' => $this->deviceType, - 'user_agent' => $this->userAgent, - 'remote_ip' => $this->remoteIp, - 'exclude_accounts' => $this->excludeAccounts, - 'fail_at' => $this->failAt->toIso8601String(), - 'fail_error_class' => $this->failErrorClass, - 'fail_message' => $this->failMessage, - 'fetch_scopes' => $this->fetchScopes, - 'finished' => $this->finished, - 'finished_recent' => $this->finishedRecent, - 'from_date' => $this->fromDate->toIso8601String(), - 'id' => $this->id, - 'interactive' => $this->interactive, - 'locale' => $this->locale, - 'partial' => $this->partial, - 'show_consent_confirmation' => $this->showConsentInformation, - 'stages' => $this->stages, - 'store_credentials' => $this->storeCredentials, - 'success_at' => $this->successAt->toIso8601String(), - 'to_date' => $this->toDate->toIso8601String(), - 'updated_at' => $this->updatedAt->toIso8601String(), - ]; - - return $array; - } - - -} diff --git a/app/Services/Spectre/Object/Customer.php b/app/Services/Spectre/Object/Customer.php deleted file mode 100644 index b526cd4195..0000000000 --- a/app/Services/Spectre/Object/Customer.php +++ /dev/null @@ -1,112 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -/** - * Class Customer - * - * @codeCoverageIgnore - * @SuppressWarnings(PHPMD.ShortVariable) - * @deprecated - */ -class Customer extends SpectreObject -{ - /** @var int */ - private $id; - /** @var string */ - private $identifier; - /** @var string */ - private $secret; - - /** - * Customer constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->id = (int)$data['id']; - $this->identifier = $data['identifier']; - $this->secret = $data['secret']; - } - - /** - * @return int - */ - public function getId(): int - { - return $this->id; - } - - /** - * @param int $id - */ - public function setId(int $id): void - { - $this->id = $id; - } - - /** - * @return string - */ - public function getIdentifier(): string - { - return $this->identifier; - } - - /** - * @param string $identifier - */ - public function setIdentifier(string $identifier): void - { - $this->identifier = $identifier; - } - - /** - * @return string - */ - public function getSecret(): string - { - return $this->secret; - } - - /** - * @param string $secret - */ - public function setSecret(string $secret): void - { - $this->secret = $secret; - } - - /** - * @return array - */ - public function toArray(): array - { - return [ - 'id' => $this->id, - 'identifier' => $this->identifier, - 'secret' => $this->secret, - ]; - } -} diff --git a/app/Services/Spectre/Object/Holder.php b/app/Services/Spectre/Object/Holder.php deleted file mode 100644 index 8c2e739342..0000000000 --- a/app/Services/Spectre/Object/Holder.php +++ /dev/null @@ -1,52 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -/** - * Class Holder - * - * @codeCoverageIgnore - * @deprecated - */ -class Holder extends SpectreObject -{ - /** - * Holder constructor. - * - * @param array $data - * - */ - public function __construct(array $data) - { - - } - - /** - * @return array - */ - public function toArray(): array - { - return []; - } -} diff --git a/app/Services/Spectre/Object/Login.php b/app/Services/Spectre/Object/Login.php deleted file mode 100644 index 55d176cb24..0000000000 --- a/app/Services/Spectre/Object/Login.php +++ /dev/null @@ -1,191 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -use Carbon\Carbon; - - -/** - * Class Login - * - * @codeCoverageIgnore - * @SuppressWarnings(PHPMD.ShortVariable) - * @SuppressWarnings(PHPMD.TooManyFields) - * @deprecated - */ -class Login extends SpectreObject -{ - /** @var Carbon */ - private $consentGivenAt; - /** @var array */ - private $consentTypes; - /** @var string */ - private $countryCode; - /** @var Carbon */ - private $createdAt; - /** @var int */ - private $customerId; - /** @var bool */ - private $dailyRefresh; - /** @var Holder */ - private $holderInfo; - /** @var int */ - private $id; - /** @var Attempt */ - private $lastAttempt; - /** @var Carbon */ - private $lastSuccessAt; - /** @var Carbon */ - private $nextRefreshPossibleAt; - /** @var string */ - private $providerCode; - /** @var int */ - private $providerId; - /** @var string */ - private $providerName; - /** @var bool */ - private $showConsentConfirmation; - /** @var string */ - private $status; - /** @var bool */ - private $storeCredentials; - /** @var Carbon */ - private $updatedAt; - - /** - * Login constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->consentGivenAt = new Carbon($data['consent_given_at']); - $this->consentTypes = $data['consent_types']; - $this->countryCode = $data['country_code']; - $this->createdAt = new Carbon($data['created_at']); - $this->updatedAt = new Carbon($data['updated_at']); - $this->customerId = $data['customer_id']; - $this->dailyRefresh = $data['daily_refresh']; - $this->holderInfo = new Holder($data['holder_info']); - $this->id = (int)$data['id']; - $this->lastAttempt = new Attempt($data['last_attempt']); - $this->lastSuccessAt = new Carbon($data['last_success_at']); - $this->nextRefreshPossibleAt = new Carbon($data['next_refresh_possible_at']); - $this->providerCode = $data['provider_code']; - $this->providerId = $data['provider_id']; - $this->providerName = $data['provider_name']; - $this->showConsentConfirmation = $data['show_consent_confirmation']; - $this->status = $data['status']; - $this->storeCredentials = $data['store_credentials']; - - } - - /** - * @return string - */ - public function getCountryCode(): string - { - return $this->countryCode; - } - - /** - * @return int - */ - public function getId(): int - { - return $this->id; - } - - /** - * @return Attempt - */ - public function getLastAttempt(): Attempt - { - return $this->lastAttempt; - } - - /** - * @return Carbon - */ - public function getLastSuccessAt(): Carbon - { - return $this->lastSuccessAt; - } - - /** - * @return string - */ - public function getProviderName(): string - { - return $this->providerName; - } - - /** - * @return string - */ - public function getStatus(): string - { - return $this->status; - } - - /** - * @return Carbon - */ - public function getUpdatedAt(): Carbon - { - return $this->updatedAt; - } - - /** - * @return array - */ - public function toArray(): array - { - $array = [ - 'consent_given_at' => $this->consentGivenAt->toIso8601String(), - 'consent_types' => $this->consentTypes, - 'country_code' => $this->countryCode, - 'created_at' => $this->createdAt->toIso8601String(), - 'updated_at' => $this->updatedAt->toIso8601String(), - 'customer_id' => $this->customerId, - 'daily_refresh' => $this->dailyRefresh, - 'holder_info' => $this->holderInfo->toArray(), - 'id' => $this->id, - 'last_attempt' => $this->lastAttempt->toArray(), - 'last_success_at' => $this->lastSuccessAt->toIso8601String(), - 'next_refresh_possible_at' => $this->nextRefreshPossibleAt->toIso8601String(), - 'provider_code' => $this->providerCode, - 'provider_id' => $this->providerId, - 'provider_name' => $this->providerName, - 'show_consent_confirmation' => $this->showConsentConfirmation, - 'status' => $this->status, - 'store_credentials' => $this->storeCredentials, - - ]; - - return $array; - } - - -} diff --git a/app/Services/Spectre/Object/SpectreObject.php b/app/Services/Spectre/Object/SpectreObject.php deleted file mode 100644 index 41030b0ff6..0000000000 --- a/app/Services/Spectre/Object/SpectreObject.php +++ /dev/null @@ -1,32 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -/** - * @codeCoverageIgnore - * Class SpectreObject - * @deprecated - */ -class SpectreObject -{ -} diff --git a/app/Services/Spectre/Object/Token.php b/app/Services/Spectre/Object/Token.php deleted file mode 100644 index f344c2c6be..0000000000 --- a/app/Services/Spectre/Object/Token.php +++ /dev/null @@ -1,90 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -use Carbon\Carbon; - -/** - * @codeCoverageIgnore - * Class Token - * @deprecated - */ -class Token extends SpectreObject -{ - /** @var string */ - private $connectUrl; - /** @var Carbon */ - private $expiresAt; - /** @var string */ - private $token; - - /** - * Token constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->token = $data['token']; - $this->expiresAt = new Carbon($data['expires_at']); - $this->connectUrl = $data['connect_url']; - } - - /** - * @return string - */ - public function getConnectUrl(): string - { - return $this->connectUrl; - } - - /** - * @return Carbon - */ - public function getExpiresAt(): Carbon - { - return $this->expiresAt; - } - - /** - * @return string - */ - public function getToken(): string - { - return $this->token; - } - - /** - * - */ - public function toArray(): array - { - return [ - 'connect_url' => $this->connectUrl, - 'expires_at' => $this->expiresAt->toW3cString(), - 'token' => $this->token, - ]; - } - -} diff --git a/app/Services/Spectre/Object/Transaction.php b/app/Services/Spectre/Object/Transaction.php deleted file mode 100644 index 62fc784d2c..0000000000 --- a/app/Services/Spectre/Object/Transaction.php +++ /dev/null @@ -1,227 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -use Carbon\Carbon; - -/** - * Class Transaction - * - * @codeCoverageIgnore - * @deprecated - * - * @SuppressWarnings(PHPMD.ShortVariable) - */ -class Transaction extends SpectreObject -{ - /** @var int */ - private $accountId; - /** @var string */ - private $amount; - /** @var string */ - private $category; - /** @var Carbon */ - private $createdAt; - /** @var string */ - private $currencyCode; - /** @var string */ - private $description; - /** @var bool */ - private $duplicated; - /** @var TransactionExtra */ - private $extra; - /** @var int */ - private $id; - /** @var Carbon */ - private $madeOn; - /** @var string */ - private $mode; - /** @var string */ - private $status; - /** @var Carbon */ - private $updatedAt; - - /** - * Transaction constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->id = (int)$data['id']; - $this->mode = $data['mode']; - $this->status = $data['status']; - $this->madeOn = new Carbon($data['made_on']); - $this->amount = $data['amount']; - $this->currencyCode = $data['currency_code']; - $this->description = $data['description']; - $this->category = $data['category']; - $this->duplicated = $data['duplicated']; - $this->extra = new TransactionExtra($data['extra'] ?? []); - $this->accountId = $data['account_id']; - $this->createdAt = new Carbon($data['created_at']); - $this->updatedAt = new Carbon($data['updated_at']); - } - - /** - * @return string - */ - public function getAmount(): string - { - return (string)$this->amount; - } - - /** - * @return string - */ - public function getCategory(): string - { - return $this->category; - } - - /** - * @return string - */ - public function getCurrencyCode(): string - { - return $this->currencyCode; - } - - /** - * @return string - */ - public function getDescription(): string - { - return $this->description; - } - - /** - * @return TransactionExtra|null - */ - public function getExtra(): ?TransactionExtra - { - return $this->extra; - } - - /** - * @return string - */ - public function getHash(): string - { - $array = [ - 'id' => $this->id, - 'mode' => $this->mode, - 'status' => $this->status, - 'made_on' => $this->madeOn->toIso8601String(), - 'amount' => $this->amount, - 'currency_code' => $this->currencyCode, - 'description' => $this->description, - 'category' => $this->category, - 'duplicated' => $this->duplicated, - 'extra' => $this->extra->toArray(), - 'account_id' => $this->accountId, - 'created_at' => $this->createdAt->toIso8601String(), - 'updated_at' => $this->updatedAt->toIso8601String(), - ]; - - return hash('sha256', json_encode($array)); - } - - /** - * @return int - */ - public function getId(): int - { - return $this->id; - } - - /** - * @return Carbon - */ - public function getMadeOn(): Carbon - { - return $this->madeOn; - } - - /** - * @return string - */ - public function getMode(): string - { - return $this->mode; - } - - /** - * Get opposing account data. - * - * @return array - * - */ - public function getOpposingAccountData(): array - { - $data = [ - 'name' => null, - 'iban' => null, - 'number' => null, - 'bic' => null, - ]; - $extra = $this->getExtra(); - if (null !== $extra) { - $arr = $extra->toArray(); - foreach ($arr as $key => $value) { - switch ($key) { - case 'account_number': - $data['number'] = $value; - $data['name'] = $data['name'] ?? (string)trans('import.spectre_account_with_number', ['number' => $value]); - break; - case 'payee': - $data['name'] = $value; - break; - default: - break; - } - } - } - - return $data; - } - - /** - * @return string - */ - public function getStatus(): string - { - return $this->status; - } - - /** - * @return bool - */ - public function isDuplicated(): bool - { - return $this->duplicated; - } - - -} diff --git a/app/Services/Spectre/Object/TransactionExtra.php b/app/Services/Spectre/Object/TransactionExtra.php deleted file mode 100644 index 160b1247a0..0000000000 --- a/app/Services/Spectre/Object/TransactionExtra.php +++ /dev/null @@ -1,174 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Object; - -use Carbon\Carbon; - -/** - * Class TransactionExtra - * - * @SuppressWarnings(PHPMD.TooManyFields) - * @SuppressWarnings(PHPMD.ShortVariable) - * @codeCoverageIgnore - * @deprecated - */ -class TransactionExtra extends SpectreObject -{ - /** @var string */ - private $accountBalanceSnapshot; - /** @var string */ - private $accountNumber; - /** @var string */ - private $additional; - /** @var string */ - private $assetAmount; - /** @var string */ - private $assetCode; - /** @var string */ - private $categorizationConfidence; - /** @var string */ - private $checkNumber; - /** @var string */ - private $customerCategoryCode; - /** @var string */ - private $customerCategoryName; - /** @var string */ - private $id; - /** @var string */ - private $information; - /** @var string */ - private $mcc; - /** @var string */ - private $originalAmount; - /** @var string */ - private $originalCategory; - /** @var string */ - private $originalCurrencyCode; - /** @var string */ - private $originalSubCategory; - /** @var string */ - private $payee; - /** @var bool */ - private $possibleDuplicate; - /** @var Carbon */ - private $postingDate; - /** @var Carbon */ - private $postingTime; - /** @var string */ - private $recordNumber; - /** @var array */ - private $tags; - /** @var Carbon */ - private $time; - /** @var string */ - private $type; - /** @var string */ - private $unitPrice; - /** @var string */ - private $units; - - /** - * TransactionExtra constructor. - * - * @param array $data - */ - public function __construct(array $data) - { - $this->id = $data['id'] ?? null; - $this->recordNumber = $data['record_number'] ?? null; - $this->information = $data['information'] ?? null; - $this->time = isset($data['time']) ? new Carbon($data['time']) : null; - $this->postingDate = isset($data['posting_date']) ? new Carbon($data['posting_date']) : null; - $this->postingTime = isset($data['posting_time']) ? new Carbon($data['posting_time']) : null; - $this->accountNumber = $data['account_number'] ?? null; - $this->originalAmount = $data['original_amount'] ?? null; - $this->originalCurrencyCode = $data['original_currency_code'] ?? null; - $this->assetCode = $data['asset_code'] ?? null; - $this->assetAmount = $data['asset_amount'] ?? null; - $this->originalCategory = $data['original_category'] ?? null; - $this->originalSubCategory = $data['original_subcategory'] ?? null; - $this->customerCategoryCode = $data['customer_category_code'] ?? null; - $this->customerCategoryName = $data['customer_category_name'] ?? null; - $this->possibleDuplicate = $data['possible_duplicate'] ?? null; - $this->tags = $data['tags'] ?? null; - $this->mcc = $data['mcc'] ?? null; - $this->payee = $data['payee'] ?? null; - $this->type = $data['type'] ?? null; - $this->checkNumber = $data['check_number'] ?? null; - $this->units = $data['units'] ?? null; - $this->additional = $data['additional'] ?? null; - $this->unitPrice = $data['unit_price'] ?? null; - $this->accountBalanceSnapshot = $data['account_balance_snapshot'] ?? null; - $this->categorizationConfidence = $data['categorization_confidence'] ?? null; - } - - /** - * @return string|null - */ - public function getId(): ?string - { - return $this->id; - } - - /** - * @return array - */ - public function toArray(): array - { - - $array = [ - 'id' => $this->id, - 'record_number' => $this->recordNumber, - 'information' => $this->information, - 'time' => null === $this->time ? null : $this->time->toIso8601String(), - 'posting_date' => null === $this->postingDate ? null : $this->postingDate->toIso8601String(), - 'posting_time' => null === $this->postingTime ? null : $this->postingTime->toIso8601String(), - 'account_number' => $this->accountNumber, - 'original_amount' => $this->originalAmount, - 'original_currency_code' => $this->originalCurrencyCode, - 'asset_code' => $this->assetCode, - 'asset_amount' => $this->assetAmount, - 'original_category' => $this->originalCategory, - 'original_subcategory' => $this->originalSubCategory, - 'customer_category_code' => $this->customerCategoryCode, - 'customer_category_name' => $this->customerCategoryName, - 'possible_duplicate' => $this->possibleDuplicate, - 'tags' => $this->tags, - 'mcc' => $this->mcc, - 'payee' => $this->payee, - 'type' => $this->type, - 'check_number' => $this->checkNumber, - 'units' => $this->units, - 'additional' => $this->additional, - 'unit_price' => $this->unitPrice, - 'account_balance_snapshot' => $this->accountBalanceSnapshot, - 'categorization_confidence' => $this->categorizationConfidence, - ]; - - - return $array; - } - - -} diff --git a/app/Services/Spectre/Request/CreateTokenRequest.php b/app/Services/Spectre/Request/CreateTokenRequest.php deleted file mode 100644 index ff47245fd5..0000000000 --- a/app/Services/Spectre/Request/CreateTokenRequest.php +++ /dev/null @@ -1,95 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Request; - -use FireflyIII\Services\Spectre\Object\Customer; -use FireflyIII\Services\Spectre\Object\Token; - - -/** - * Class CreateTokenRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class CreateTokenRequest extends SpectreRequest -{ - /** @var Customer */ - private $customer; - - /** @var Token */ - private $token; - - /** @var string */ - private $uri; - - /** - * - * @throws \FireflyIII\Exceptions\FireflyException - */ - public function call(): void - { - // add mandatory fields to login object - $data = [ - 'data' => [ - 'customer_id' => $this->customer->getId(), - 'fetch_scopes' => ['accounts', 'transactions'], - 'daily_refresh' => true, - 'include_fake_providers' => true, - 'show_consent_confirmation' => true, - 'credentials_strategy' => 'ask', - 'return_to' => $this->uri, - ], - ]; - $uri = '/api/v4/tokens/create'; - $response = $this->sendSignedSpectrePost($uri, $data); - $this->token = new Token($response['data']); - } - - /** - * @return Token - */ - public function getToken(): Token - { - return $this->token; - } - - /** - * @param Customer $customer - */ - public function setCustomer(Customer $customer): void - { - $this->customer = $customer; - } - - /** - * @param string $uri - */ - public function setUri(string $uri): void - { - $this->uri = $uri; - } - - -} diff --git a/app/Services/Spectre/Request/ListAccountsRequest.php b/app/Services/Spectre/Request/ListAccountsRequest.php deleted file mode 100644 index 95f870018e..0000000000 --- a/app/Services/Spectre/Request/ListAccountsRequest.php +++ /dev/null @@ -1,93 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Request; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Services\Spectre\Object\Account; -use FireflyIII\Services\Spectre\Object\Login; -use Log; - -/** - * Class ListAccountsRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class ListAccountsRequest extends SpectreRequest -{ - /** @var array */ - private $accounts = []; - /** @var Login */ - private $login; - - /** - * @throws FireflyException - * - */ - public function call(): void - { - $hasNextPage = true; - $nextId = 0; - while ($hasNextPage) { - Log::debug(sprintf('Now calling ListAccountsRequest for next_id %d', $nextId)); - $parameters = ['from_id' => $nextId, 'login_id' => $this->login->getId()]; - $uri = '/api/v4/accounts?' . http_build_query($parameters); - $response = $this->sendSignedSpectreGet($uri, []); - - // count entries: - Log::debug(sprintf('Found %d entries in data-array', count($response['data']))); - - // extract next ID - $hasNextPage = false; - if (isset($response['meta']['next_id']) && (int)$response['meta']['next_id'] > $nextId) { - $hasNextPage = true; - $nextId = $response['meta']['next_id']; - Log::debug(sprintf('Next ID is now %d.', $nextId)); - } - - // store customers: - foreach ($response['data'] as $accountArray) { - $this->accounts[] = new Account($accountArray); - } - } - } - - /** - * @return array - */ - public function getAccounts(): array - { - return $this->accounts; - } - - /** - * @param Login $login - */ - public function setLogin(Login $login): void - { - $this->login = $login; - } - - -} diff --git a/app/Services/Spectre/Request/ListCustomersRequest.php b/app/Services/Spectre/Request/ListCustomersRequest.php deleted file mode 100644 index 6fd6a823c7..0000000000 --- a/app/Services/Spectre/Request/ListCustomersRequest.php +++ /dev/null @@ -1,83 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Request; - -use FireflyIII\Services\Spectre\Object\Customer; -use Log; - - -/** - * Class ListCustomersRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class ListCustomersRequest extends SpectreRequest -{ - /** @var array */ - private $customers = []; - - /** - * - * @throws \FireflyIII\Exceptions\FireflyException - * - */ - public function call(): void - { - $hasNextPage = true; - $nextId = 0; - while ($hasNextPage) { - Log::debug(sprintf('Now calling ListCustomersRequest for next_id %d', $nextId)); - $parameters = ['from_id' => $nextId]; - $uri = '/api/v4/customers/?' . http_build_query($parameters); - $response = $this->sendSignedSpectreGet($uri, []); - - // count entries: - Log::debug(sprintf('Found %d entries in data-array', count($response['data']))); - - // extract next ID - $hasNextPage = false; - if (isset($response['meta']['next_id']) && (int)$response['meta']['next_id'] > $nextId) { - $hasNextPage = true; - $nextId = $response['meta']['next_id']; - Log::debug(sprintf('Next ID is now %d.', $nextId)); - } - - // store customers: - foreach ($response['data'] as $customerArray) { - $this->customers[] = new Customer($customerArray); - } - } - } - - /** - * @return array - */ - public function getCustomers(): array - { - return $this->customers; - } - - -} diff --git a/app/Services/Spectre/Request/ListLoginsRequest.php b/app/Services/Spectre/Request/ListLoginsRequest.php deleted file mode 100644 index 9c310f7dd4..0000000000 --- a/app/Services/Spectre/Request/ListLoginsRequest.php +++ /dev/null @@ -1,103 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Request; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Services\Spectre\Object\Customer; -use FireflyIII\Services\Spectre\Object\Login; -use Illuminate\Support\Collection; -use Log; - -/** - * Class ListLoginsRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class ListLoginsRequest extends SpectreRequest -{ - /** @var Customer */ - private $customer; - - /** @var array */ - private $logins = []; - - /** - * @throws FireflyException - * - */ - public function call(): void - { - $hasNextPage = true; - $nextId = 0; - while ($hasNextPage) { - Log::debug(sprintf('Now calling ListLoginsRequest for next_id %d', $nextId)); - $parameters = ['from_id' => $nextId, 'customer_id' => $this->customer->getId()]; - $uri = '/api/v4/logins/?' . http_build_query($parameters); - $response = $this->sendSignedSpectreGet($uri, []); - - // count entries: - Log::debug(sprintf('Found %d entries in data-array', count($response['data']))); - - // extract next ID - $hasNextPage = false; - if (isset($response['meta']['next_id']) && (int)$response['meta']['next_id'] > $nextId) { - $hasNextPage = true; - $nextId = $response['meta']['next_id']; - Log::debug(sprintf('Next ID is now %d.', $nextId)); - } - $collection = new Collection; - // store logins: - /** @var array $loginArray */ - foreach ($response['data'] as $loginArray) { - $collection->push(new Login($loginArray)); - } - // sort logins by date created: - $sorted = $collection->sortByDesc( - static function (Login $login) { - return $login->getUpdatedAt()->timestamp; - } - ); - $this->logins = $sorted->toArray(); - } - } - - /** - * @return array - */ - public function getLogins(): array - { - return $this->logins; - } - - /** - * @param Customer $customer - */ - public function setCustomer(Customer $customer): void - { - $this->customer = $customer; - } - - -} diff --git a/app/Services/Spectre/Request/ListTransactionsRequest.php b/app/Services/Spectre/Request/ListTransactionsRequest.php deleted file mode 100644 index 015599273a..0000000000 --- a/app/Services/Spectre/Request/ListTransactionsRequest.php +++ /dev/null @@ -1,94 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Request; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Services\Spectre\Object\Account; -use FireflyIII\Services\Spectre\Object\Transaction; -use Log; - -/** - * Class ListTransactionsRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class ListTransactionsRequest extends SpectreRequest -{ - /** @var Account */ - private $account; - /** @var array */ - private $transactions = []; - - /** - * @throws FireflyException - * - */ - public function call(): void - { - $hasNextPage = true; - $nextId = 0; - while ($hasNextPage) { - Log::debug(sprintf('Now calling ListTransactionsRequest for next_id %d', $nextId)); - $parameters = ['from_id' => $nextId, 'account_id' => $this->account->getId()]; - $uri = '/api/v4/transactions?' . http_build_query($parameters); - $response = $this->sendSignedSpectreGet($uri, []); - - // count entries: - Log::debug(sprintf('Found %d entries in data-array', count($response['data']))); - - // extract next ID - $hasNextPage = false; - if (isset($response['meta']['next_id']) && (int)$response['meta']['next_id'] > $nextId) { - $hasNextPage = true; - $nextId = $response['meta']['next_id']; - Log::debug(sprintf('Next ID is now %d.', $nextId)); - } - - // store customers: - foreach ($response['data'] as $transactionArray) { - $this->transactions[] = new Transaction($transactionArray); - } - } - } - - /** - * @return array - */ - public function getTransactions(): array - { - return $this->transactions; - } - - - /** - * @param Account $account - */ - public function setAccount(Account $account): void - { - $this->account = $account; - } - - -} diff --git a/app/Services/Spectre/Request/NewCustomerRequest.php b/app/Services/Spectre/Request/NewCustomerRequest.php deleted file mode 100644 index 1c7aa32ffc..0000000000 --- a/app/Services/Spectre/Request/NewCustomerRequest.php +++ /dev/null @@ -1,63 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Request; - -use FireflyIII\Services\Spectre\Object\Customer; -use Log; - -/** - * Class NewCustomerRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class NewCustomerRequest extends SpectreRequest -{ - /** @var Customer */ - protected $customer; - - /** - * @throws \FireflyIII\Exceptions\FireflyException - */ - public function call(): void - { - $data = [ - 'data' => [ - 'identifier' => 'default_ff3_customer', - ], - ]; - $uri = '/api/v4/customers/'; - Log::debug(sprintf('Going to call %s with info:', $uri), $data); - $response = $this->sendSignedSpectrePost($uri, $data); - // create customer: - $this->customer = new Customer($response['data']); - } - - /** - * @return Customer - */ - public function getCustomer(): Customer - { - return $this->customer; - } -} diff --git a/app/Services/Spectre/Request/SpectreRequest.php b/app/Services/Spectre/Request/SpectreRequest.php deleted file mode 100644 index f9e959c237..0000000000 --- a/app/Services/Spectre/Request/SpectreRequest.php +++ /dev/null @@ -1,308 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Services\Spectre\Request; - -use Exception; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\User; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\GuzzleException; -use Log; -use RuntimeException; - -/** - * Class SpectreRequest - * - * @codeCoverageIgnore - * @deprecated - */ -abstract class SpectreRequest -{ - /** @var int */ - protected $expiresAt = 0; - /** @var string */ - private $appId; - /** @var string */ - private $privateKey; - /** @var string */ - private $secret; - /** @var string */ - private $server; - /** @var User */ - private $user; - - /** - * - */ - abstract public function call(): void; - - /** - * @codeCoverageIgnore - * @return string - */ - public function getAppId(): string - { - return $this->appId; - } - - /** - * @codeCoverageIgnore - * - * @param string $appId - */ - public function setAppId(string $appId): void - { - $this->appId = $appId; - } - - /** - * @codeCoverageIgnore - * @return string - */ - public function getSecret(): string - { - return $this->secret; - } - - /** - * @codeCoverageIgnore - * - * @param string $secret - */ - public function setSecret(string $secret): void - { - $this->secret = $secret; - } - - /** - * @codeCoverageIgnore - * @return string - */ - public function getServer(): string - { - return $this->server; - } - - /** - * @codeCoverageIgnore - * - * @param string $privateKey - */ - public function setPrivateKey(string $privateKey): void - { - $this->privateKey = $privateKey; - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - $this->server = 'https://' . config('import.options.spectre.server'); - $this->expiresAt = time() + 180; - $privateKey = app('preferences')->getForUser($user, 'spectre_private_key', null); - $this->privateKey = $privateKey->data; - - // set client ID - $appId = app('preferences')->getForUser($user, 'spectre_app_id', null); - if (null !== $appId && '' !== (string)$appId->data) { - $this->appId = $appId->data; - } - - // set service secret - $secret = app('preferences')->getForUser($user, 'spectre_secret', null); - if (null !== $secret && '' !== (string)$secret->data) { - $this->secret = $secret->data; - } - } - - /** - * @param string $method - * @param string $uri - * @param string $data - * - * @return string - * - * @throws FireflyException - */ - protected function generateSignature(string $method, string $uri, string $data): string - { - if ('' === $this->privateKey) { - throw new FireflyException('No private key present.'); - } - $method = strtolower($method); - if ('get' === $method || 'delete' === $method) { - $data = ''; - } - $toSign = $this->expiresAt . '|' . strtoupper($method) . '|' . $uri . '|' . $data . ''; // no file so no content there. - Log::debug(sprintf('String to sign: "%s"', $toSign)); - $signature = ''; - - // Sign the data - openssl_sign($toSign, $signature, $this->privateKey, OPENSSL_ALGO_SHA256); - $signature = base64_encode($signature); - - return $signature; - } - - /** - * @return array - */ - protected function getDefaultHeaders(): array - { - $userAgent = sprintf('FireflyIII v%s', config('firefly.version')); - - return [ - 'App-id' => $this->getAppId(), - 'Secret' => $this->getSecret(), - 'Accept' => 'application/json', - 'Content-type' => 'application/json', - 'Cache-Control' => 'no-cache', - 'User-Agent' => $userAgent, - 'Expires-at' => $this->expiresAt, - ]; - } - - /** - * @param string $uri - * @param array $data - * - * @return array - * - * @throws FireflyException - */ - protected function sendSignedSpectreGet(string $uri, array $data): array - { - if ('' === $this->server) { - throw new FireflyException('No Spectre server defined'); - } - - $headers = $this->getDefaultHeaders(); - $sendBody = json_encode($data); // OK - $fullUri = $this->server . $uri; - $signature = $this->generateSignature('get', $fullUri, $sendBody); - $headers['Signature'] = $signature; - - Log::debug('Final headers for spectre signed get request:', $headers); - try { - $client = new Client; - $res = $client->request('GET', $fullUri, ['headers' => $headers]); - } catch (GuzzleException|Exception $e) { - throw new FireflyException(sprintf('Guzzle Exception: %s', $e->getMessage())); - } - $statusCode = $res->getStatusCode(); - try { - $returnBody = $res->getBody()->getContents(); - } catch (RuntimeException $e) { - Log::error(sprintf('Could not get body from SpectreRequest::GET result: %s', $e->getMessage())); - $returnBody = ''; - } - $this->detectError($returnBody, $statusCode); - - $array = json_decode($returnBody, true); - $responseHeaders = $res->getHeaders(); - $array['ResponseHeaders'] = $responseHeaders; - $array['ResponseStatusCode'] = $statusCode; - - if (isset($array['error_class'])) { - $message = $array['error_message'] ?? '(no message)'; - throw new FireflyException(sprintf('Error of class %s: %s', $array['error_class'], $message)); - } - - - return $array; - } - - /** - * @param string $uri - * @param array $data - * - * @return array - * - * @throws FireflyException - */ - protected function sendSignedSpectrePost(string $uri, array $data): array - { - if ('' === $this->server) { - throw new FireflyException('No Spectre server defined'); - } - - $headers = $this->getDefaultHeaders(); - $body = json_encode($data); - $fullUri = $this->server . $uri; - $signature = $this->generateSignature('post', $fullUri, $body); - $headers['Signature'] = $signature; - - Log::debug('Final headers for spectre signed POST request:', $headers); - try { - $client = new Client; - $res = $client->request('POST', $fullUri, ['headers' => $headers, 'body' => $body]); - } catch (GuzzleException|Exception $e) { - throw new FireflyException(sprintf('Guzzle Exception: %s', $e->getMessage())); - } - - try { - $body = $res->getBody()->getContents(); - } catch (RuntimeException $e) { - Log::error(sprintf('Could not get body from SpectreRequest::POST result: %s', $e->getMessage())); - $body = ''; - } - - $statusCode = $res->getStatusCode(); - $this->detectError($body, $statusCode); - - $array = json_decode($body, true); - $responseHeaders = $res->getHeaders(); - $array['ResponseHeaders'] = $responseHeaders; - $array['ResponseStatusCode'] = $statusCode; - - return $array; - } - - /** - * @param string $body - * - * @param int $statusCode - * - * @throws FireflyException - */ - private function detectError(string $body, int $statusCode): void - { - $array = json_decode($body, true); - if (isset($array['error_class'])) { - $message = $array['error_message'] ?? '(no message)'; - $errorClass = $array['error_class']; - $class = sprintf('\\FireflyIII\\Services\\Spectre\Exception\\%sException', $errorClass); - if (class_exists($class)) { - throw new $class($message); - } - - throw new FireflyException(sprintf('Error of class %s: %s', $errorClass, $message)); - } - - if (200 !== $statusCode) { - throw new FireflyException(sprintf('Status code %d: %s', $statusCode, $body)); - } - } -} diff --git a/app/Services/Ynab/Request/GetAccountsRequest.php b/app/Services/Ynab/Request/GetAccountsRequest.php deleted file mode 100644 index 147dd287a6..0000000000 --- a/app/Services/Ynab/Request/GetAccountsRequest.php +++ /dev/null @@ -1,57 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Ynab\Request; - -use Log; - -/** - * Class GetAccountsRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class GetAccountsRequest extends YnabRequest -{ - /** @var array */ - public $accounts; - /** @var string */ - public $budgetId; - - /** - * - */ - public function call(): void - { - Log::debug('Now in GetAccountsRequest::call()'); - $uri = $this->api . sprintf('/budgets/%s/accounts', $this->budgetId); - - Log::debug(sprintf('URI is %s', $uri)); - - $result = $this->authenticatedGetRequest($uri, []); - //Log::debug('Raw GetAccountsRequest result', $result); - - // expect data in [data][accounts] - $this->accounts = $result['data']['accounts'] ?? []; - } -} diff --git a/app/Services/Ynab/Request/GetBudgetsRequest.php b/app/Services/Ynab/Request/GetBudgetsRequest.php deleted file mode 100644 index b392964a69..0000000000 --- a/app/Services/Ynab/Request/GetBudgetsRequest.php +++ /dev/null @@ -1,73 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Ynab\Request; - -use Log; - -/** - * Class GetBudgetsRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class GetBudgetsRequest extends YnabRequest -{ - /** @var array */ - public $budgets; - - public function __construct() - { - parent::__construct(); - $this->budgets = []; - } - - /** - * - */ - public function call(): void - { - Log::debug('Now in GetBudgetsRequest::call()'); - $uri = $this->api . '/budgets'; - - Log::debug(sprintf('URI is %s', $uri)); - - $result = $this->authenticatedGetRequest($uri, []); - Log::debug('Raw GetBudgetsRequest result', $result); - - // expect data in [data][budgets] - $rawBudgets = $result['data']['budgets'] ?? []; - $freshBudgets = []; - foreach ($rawBudgets as $rawBudget) { - Log::debug(sprintf('Raw content of budget is: %s', json_encode($rawBudget))); - Log::debug(sprintf('Content of currency format is: %s', json_encode($rawBudget['currency_format'] ?? []))); - Log::debug(sprintf('ISO code is: %s', $rawBudget['currency_format']['iso_code'] ?? '(none)')); - $freshBudgets[] = [ - 'id' => $rawBudget['id'], - 'name' => $rawBudget['name'], - 'currency_code' => $rawBudget['currency_format']['iso_code'] ?? null, - ]; - } - $this->budgets = $freshBudgets; - } -} diff --git a/app/Services/Ynab/Request/GetTransactionsRequest.php b/app/Services/Ynab/Request/GetTransactionsRequest.php deleted file mode 100644 index 3a3fe1a5ac..0000000000 --- a/app/Services/Ynab/Request/GetTransactionsRequest.php +++ /dev/null @@ -1,61 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Ynab\Request; - -use Log; - -/** - * Class GetTransactionsRequest - * - * @codeCoverageIgnore - * @deprecated - */ -class GetTransactionsRequest extends YnabRequest -{ - /** @var string */ - public $accountId; - /** @var array */ - public $accounts; - /** @var string */ - public $budgetId; - /** @var array */ - public $transactions; - - /** - * - */ - public function call(): void - { - Log::debug('Now in GetTransactionsRequest::call()'); - $uri = $this->api . sprintf('/budgets/%s/accounts/%s/transactions', $this->budgetId, $this->accountId); - - Log::debug(sprintf('URI is %s', $uri)); - - $result = $this->authenticatedGetRequest($uri, []); - //Log::debug('Raw GetTransactionsRequest result', $result); - - // expect data in [data][transactions] - $this->transactions = $result['data']['transactions'] ?? []; - } -} diff --git a/app/Services/Ynab/Request/YnabRequest.php b/app/Services/Ynab/Request/YnabRequest.php deleted file mode 100644 index 7a2034342f..0000000000 --- a/app/Services/Ynab/Request/YnabRequest.php +++ /dev/null @@ -1,104 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Services\Ynab\Request; - -use GuzzleHttp\Client; -use GuzzleHttp\Exception\GuzzleException; -use Log; -use RuntimeException; - -/** - * Class YnabRequest - * - * @codeCoverageIgnore - * @deprecated - */ -abstract class YnabRequest -{ - /** @var string */ - protected $api; - - /** @var string */ - protected $token; - - public function __construct() - { - $this->api = 'https://' . config('import.options.ynab.live') . '/' . config('import.options.ynab.version'); - } - - /** - * @param string $uri - * @param array|null $params - * - * @return array - */ - public function authenticatedGetRequest(string $uri, array $params = null): array - { - Log::debug(sprintf('Now in YnabRequest::authenticatedGetRequest(%s)', $uri), $params); - $client = new Client; - $params = $params ?? []; - $options = [ - 'headers' => [ - 'Authorization' => 'Bearer ' . $this->token, - ], - ]; - if (count($params) > 0) { - $uri = $uri . '?' . http_build_query($params); - } - Log::debug(sprintf('Going to call YNAB on URI: %s', $uri), $options); - try { - $res = $client->request('get', $uri, $options); - } catch (GuzzleException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - - return []; - } - try { - $content = trim($res->getBody()->getContents()); - Log::debug(sprintf('Raw body is: %s', $content)); - } catch (RuntimeException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - - return []; - } - - return json_decode($content, true) ?? []; - } - - /** - * - */ - abstract public function call(): void; - - /** - * @param string $token - */ - public function setAccessToken(string $token): void - { - $this->token = $token; - } - -} diff --git a/app/Support/Authentication/RemoteUserGuard.php b/app/Support/Authentication/RemoteUserGuard.php new file mode 100644 index 0000000000..96e37d52a8 --- /dev/null +++ b/app/Support/Authentication/RemoteUserGuard.php @@ -0,0 +1,122 @@ +application = $app; + $this->provider = $provider; + $this->user = null; + } + + /** + * + */ + public function authenticate(): void + { + Log::debug(sprintf('Now at %s', __METHOD__)); + if (!is_null($this->user)) { + Log::debug('No user found.'); + + return; + } + // Get the user identifier from $_SERVER + $userID = request()->server('REMOTE_USER') ?? null; + if (null === $userID) { + Log::debug('No user in REMOTE_USER.'); + throw new FireflyException('The REMOTE_USER header was unexpectedly empty.'); + } + + + // do some basic debugging here: + // $userID = 'test@firefly'; + + /** @var User $user */ + $user = $this->provider->retrieveById($userID); + + Log::debug(sprintf('Result of getting user from provider: %s', $user->email)); + $this->user = $user; + } + + /** + * @inheritDoc + */ + public function check(): bool + { + $result = !is_null($this->user()); + Log::debug(sprintf('Now in check(). Will return %s', var_export($result, true))); + + return $result; + } + + /** + * @inheritDoc + */ + public function guest(): bool + { + //Log::debug(sprintf('Now at %s', __METHOD__)); + return !$this->check(); + } + + /** + * @inheritDoc + */ + public function id(): ?User + { + //Log::debug(sprintf('Now at %s', __METHOD__)); + return $this->user; + } + + /** + * @inheritDoc + */ + public function setUser(Authenticatable $user) + { + //Log::debug(sprintf('Now at %s', __METHOD__)); + $this->user = $user; + } + + /** + * @inheritDoc + */ + public function user(): ?User + { + //Log::debug(sprintf('Now in user(). Will return NULL: %s', var_export(null === $this->user, true))); + return $this->user; + } + + /** + * @inheritDoc + */ + public function validate(array $credentials = []) + { + throw new FireflyException('Did not implement RemoteUserGuard::validate()'); + } +} diff --git a/app/Support/Authentication/RemoteUserProvider.php b/app/Support/Authentication/RemoteUserProvider.php new file mode 100644 index 0000000000..52dd983e75 --- /dev/null +++ b/app/Support/Authentication/RemoteUserProvider.php @@ -0,0 +1,89 @@ +first(); + if (null === $user) { + Log::debug(sprintf('User with email "%s" not found. Will be created.', $identifier)); + $user = User::create( + [ + 'blocked' => false, + 'blocked_code' => null, + 'email' => $identifier, + 'password' => bcrypt(Str::random(64)), + ] + ); + } + Log::debug(sprintf('Going to return user #%d (%s)', $user->id, $user->email)); + + return $user; + } + + /** + * @inheritDoc + */ + public function retrieveByToken($identifier, $token) + { + Log::debug(sprintf('Now at %s', __METHOD__)); + throw new FireflyException(sprintf('Did not implement %s', __METHOD__)); + } + + /** + * @inheritDoc + */ + public function updateRememberToken(Authenticatable $user, $token) + { + Log::debug(sprintf('Now at %s', __METHOD__)); + throw new FireflyException(sprintf('Did not implement %s', __METHOD__)); + } + + /** + * @inheritDoc + */ + public function validateCredentials(Authenticatable $user, array $credentials) + { + Log::debug(sprintf('Now at %s', __METHOD__)); + throw new FireflyException(sprintf('Did not implement %s', __METHOD__)); + } +} diff --git a/app/Support/Binder/ImportProvider.php b/app/Support/Binder/ImportProvider.php deleted file mode 100644 index b2b57cbf98..0000000000 --- a/app/Support/Binder/ImportProvider.php +++ /dev/null @@ -1,111 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Support\Binder; - -use Carbon\Carbon; -use FireflyIII\Import\Prerequisites\PrerequisitesInterface; -use FireflyIII\Repositories\User\UserRepositoryInterface; -use FireflyIII\User; -use Illuminate\Routing\Route; -use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; - -/** - * Class ImportProvider. - * - * @deprecated - */ -class ImportProvider implements BinderInterface -{ - /** - * @return array - * - */ - public static function getProviders(): array - { - $repository = app(UserRepositoryInterface::class); - // get and filter all import routines: - - if (!auth()->check()) { - return []; - } - - /** @var User $user */ - $user = auth()->user(); - - /** @var array $config */ - $providerNames = array_keys(config('import.enabled')); - $providers = []; - $isDemoUser = $repository->hasRole($user, 'demo'); - $isDebug = (bool)config('app.debug'); - foreach ($providerNames as $providerName) { - // only consider enabled providers - $enabled = (bool)config(sprintf('import.enabled.%s', $providerName)); - $allowedForUser = (bool)config(sprintf('import.allowed_for_user.%s', $providerName)); - $allowedForDemo = (bool)config(sprintf('import.allowed_for_demo.%s', $providerName)); - if (false === $enabled) { - continue; - } - if (false === $allowedForUser && !$isDemoUser) { - continue; - } - if (false === $allowedForDemo && $isDemoUser) { - continue; - } - - $providers[$providerName] = [ - 'has_prereq' => (bool)config('import.has_prereq.' . $providerName), - 'allowed_for_demo' => (bool)config(sprintf('import.allowed_for_demo.%s', $providerName)), - ]; - $class = (string)config(sprintf('import.prerequisites.%s', $providerName)); - $result = false; - if ('' !== $class && class_exists($class)) { - //Log::debug('Will not check prerequisites.'); - /** @var PrerequisitesInterface $object */ - $object = app($class); - $object->setUser($user); - $result = $object->isComplete(); - } - $providers[$providerName]['prereq_complete'] = $result; - } - //Log::debug(sprintf('Enabled providers: %s', json_encode(array_keys($providers)))); - - return $providers; - } - - /** - * @param string $value - * @param Route $route - * - * @return string - * - * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException - */ - public static function routeBinder(string $value, Route $route): string - { - $providers = array_keys(self::getProviders()); - if (in_array($value, $providers, true)) { - return $value; - } - throw new NotFoundHttpException; - } -} diff --git a/app/Support/Export/ExportDataGenerator.php b/app/Support/Export/ExportDataGenerator.php index d69e4eea4d..1e49f73d32 100644 --- a/app/Support/Export/ExportDataGenerator.php +++ b/app/Support/Export/ExportDataGenerator.php @@ -656,11 +656,11 @@ class ExportDataGenerator // TODO better place for keys? $header = ['user_id', 'group_id', 'journal_id', 'created_at', 'updated_at', 'group_title', 'type', 'amount', 'foreign_amount', 'currency_code', 'foreign_currency_code', 'description', 'date', 'source_name', 'source_iban', 'source_type', 'destination_name', 'destination_iban', - 'destination_type', 'reconciled', 'category', 'budget', 'bill', 'tags',]; + 'destination_type', 'reconciled', 'category', 'budget', 'bill', 'tags', 'notes']; $collector = app(GroupCollectorInterface::class); $collector->setUser($this->user); $collector->setRange($this->start, $this->end)->withAccountInformation()->withCategoryInformation()->withBillInformation() - ->withBudgetInformation()->withTagInformation(); + ->withBudgetInformation()->withTagInformation()->withNotes(); $journals = $collector->getExtractedJournals(); $records = []; @@ -691,6 +691,7 @@ class ExportDataGenerator $journal['budget_name'], $journal['bill_name'], $this->mergeTags($journal['tags']), + $journal['notes'], ]; } diff --git a/app/Support/FinTS/FinTS.php b/app/Support/FinTS/FinTS.php deleted file mode 100644 index 91dfbe21ad..0000000000 --- a/app/Support/FinTS/FinTS.php +++ /dev/null @@ -1,122 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Support\FinTS; - -use Fhp\Model\SEPAAccount; -use FireflyIII\Exceptions\FireflyException; -use Illuminate\Support\Facades\Crypt; - -/** - * @codeCoverageIgnore - * @deprecated - * Class FinTS - */ -class FinTS -{ - /** @var \Fhp\FinTs */ - private $finTS; - - /** - * @param array $config - * - * @throws FireflyException - */ - public function __construct(array $config) - { - if (!isset($config['fints_url'], $config['fints_port'], $config['fints_bank_code'], $config['fints_username'], $config['fints_password'])) { - throw new FireflyException('Constructed FinTS with incomplete config.'); - } - $this->finTS = new \Fhp\FinTs( - $config['fints_url'], - $config['fints_port'], - $config['fints_bank_code'], - $config['fints_username'], - Crypt::decrypt($config['fints_password']) // verified - ); - } - - /** - * @return bool|string - */ - public function checkConnection() - { - try { - $this->finTS->getSEPAAccounts(); - - return true; - } catch (\Exception $exception) { - return $exception->getMessage(); - } - } - - /** - * @param string $accountNumber - * - * @return SEPAAccount - * @throws FireflyException - */ - public function getAccount(string $accountNumber): SEPAAccount - { - $accounts = $this->getAccounts(); - $filteredAccounts = array_filter( - $accounts, function (SEPAAccount $account) use ($accountNumber) { - return $account->getAccountNumber() === $accountNumber; - } - ); - if (1 !== count($filteredAccounts)) { - throw new FireflyException(sprintf('Cannot find account with number "%s"', $accountNumber)); - } - - return reset($filteredAccounts); - } - - /** - * @return SEPAAccount[] - * @throws FireflyException - */ - public function getAccounts(): ?array - { - try { - return $this->finTS->getSEPAAccounts(); - } catch (\Exception $exception) { - throw new FireflyException($exception->getMessage()); - } - } - - /** - * @param SEPAAccount $account - * @param \DateTime $from - * @param \DateTIme $to - * - * @return \Fhp\Model\StatementOfAccount\StatementOfAccount|null - * @throws FireflyException - */ - public function getStatementOfAccount(SEPAAccount $account, \DateTime $from, \DateTIme $to) - { - try { - return $this->finTS->getStatementOfAccount($account, $from, $to); - } catch (\Exception $exception) { - throw new FireflyException($exception->getMessage()); - } - } -} diff --git a/app/Support/FinTS/MetadataParser.php b/app/Support/FinTS/MetadataParser.php deleted file mode 100644 index 6a079202cd..0000000000 --- a/app/Support/FinTS/MetadataParser.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Support\FinTS; - -use Fhp\Model\StatementOfAccount\Transaction as FinTSTransaction; - -/** - * @deprecated - * @codeCoverageIgnore - * Class MetadataParser - */ -class MetadataParser -{ - /** - * @param FinTSTransaction $transaction - * - * @return string - */ - public function getDescription(FinTSTransaction $transaction): string - { - //Given a description like 'EREF+AbcCRED+DE123SVWZ+DefABWA+Ghi' or 'EREF+AbcCRED+DE123SVWZ+Def' return 'Def' - $finTSDescription = $transaction->getDescription1(); - $matches = []; - if (1 === preg_match('/SVWZ\+([^\+]*)([A-Z]{4}\+|$)/', $finTSDescription, $matches)) { - return $matches[1]; - } - - return $finTSDescription; - } -} diff --git a/app/Support/Http/Controllers/CreateStuff.php b/app/Support/Http/Controllers/CreateStuff.php index 24733937a2..98f51e027f 100644 --- a/app/Support/Http/Controllers/CreateStuff.php +++ b/app/Support/Http/Controllers/CreateStuff.php @@ -27,9 +27,6 @@ use Carbon\Carbon; use Exception; use FireflyIII\Exceptions\FireflyException; use FireflyIII\Http\Requests\NewUserFormRequest; -use FireflyIII\Import\JobConfiguration\JobConfigurationInterface; -use FireflyIII\Import\Storage\ImportArrayStorage; -use FireflyIII\Models\ImportJob; use FireflyIII\Models\TransactionCurrency; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\User; @@ -174,46 +171,4 @@ trait CreateStuff ); } - /** - * Make a configurator object. - * - * @param ImportJob $importJob - * - * @return JobConfigurationInterface - * - * @throws FireflyException - */ - protected function makeConfigurator(ImportJob $importJob): JobConfigurationInterface // make object - { - $key = sprintf('import.configuration.%s', $importJob->provider); - $className = (string)config($key); - if (null === $className || !class_exists($className)) { - throw new FireflyException(sprintf('Cannot find configurator class for job with provider "%s".', $importJob->provider)); // @codeCoverageIgnore - } - Log::debug(sprintf('Going to create class "%s"', $className)); - /** @var JobConfigurationInterface $configurator */ - $configurator = app($className); - $configurator->setImportJob($importJob); - - return $configurator; - } - - /** - * Store the transactions. - * - * @param ImportJob $importJob - * - * @throws FireflyException - */ - protected function storeTransactions(ImportJob $importJob): void // make object + execute - { - /** @var ImportArrayStorage $storage */ - $storage = app(ImportArrayStorage::class); - $storage->setImportJob($importJob); - try { - $storage->store(); - } catch (FireflyException|Exception $e) { - throw new FireflyException($e->getMessage()); - } - } } diff --git a/app/Support/Import/Information/GetSpectreCustomerTrait.php b/app/Support/Import/Information/GetSpectreCustomerTrait.php deleted file mode 100644 index c2f0cd9058..0000000000 --- a/app/Support/Import/Information/GetSpectreCustomerTrait.php +++ /dev/null @@ -1,110 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Information; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Services\Spectre\Object\Customer; -use FireflyIII\Services\Spectre\Request\ListCustomersRequest; -use FireflyIII\Services\Spectre\Request\NewCustomerRequest; -use Log; - -/** - * Trait GetSpectreCustomerTrait - * - * @codeCoverageIgnore - * @deprecated - */ -trait GetSpectreCustomerTrait -{ - /** - * @param ImportJob $importJob - * - * @return Customer - * @throws FireflyException - */ - protected function getCustomer(ImportJob $importJob): Customer - { - Log::debug('Now in GetSpectreCustomerTrait::getCustomer()'); - $customer = $this->getExistingCustomer($importJob); - if (null === $customer) { - Log::debug('The customer is NULL, will fire a newCustomerRequest.'); - /** @var NewCustomerRequest $request */ - $request = app(NewCustomerRequest::class); - $request->setUser($importJob->user); - $request->call(); - - $customer = $request->getCustomer(); - - } - - Log::debug('The customer is not null.'); - - return $customer; - } - - /** - * @param ImportJob $importJob - * - * @return Customer|null - * @throws FireflyException - */ - protected function getExistingCustomer(ImportJob $importJob): ?Customer - { - Log::debug('Now in GetSpectreCustomerTrait::getExistingCustomer()'); - $customer = null; - - // check users preferences. - $preference = app('preferences')->getForUser($importJob->user, 'spectre_customer', null); - if (null !== $preference) { - Log::debug('Customer is in user configuration'); - $customer = new Customer($preference->data); - - return $customer; - } - - /** @var ListCustomersRequest $request */ - $request = app(ListCustomersRequest::class); - $request->setUser($importJob->user); - $request->call(); - $customers = $request->getCustomers(); - - Log::debug(sprintf('Found %d customer(s)', count($customers))); - /** @var Customer $current */ - foreach ($customers as $current) { - if ('default_ff3_customer' === $current->getIdentifier()) { - $customer = $current; - Log::debug('Found the correct customer.'); - break; - } - Log::debug(sprintf('Skip customer with name "%s"', $current->getIdentifier())); - } - if (null !== $customer) { - // store in preferences. - app('preferences')->setForUser($importJob->user, 'spectre_customer', $customer->toArray()); - } - - return $customer; - } -} diff --git a/app/Support/Import/Information/GetSpectreTokenTrait.php b/app/Support/Import/Information/GetSpectreTokenTrait.php deleted file mode 100644 index 875c905c8e..0000000000 --- a/app/Support/Import/Information/GetSpectreTokenTrait.php +++ /dev/null @@ -1,60 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Information; - -use FireflyIII\Models\ImportJob; -use FireflyIII\Services\Spectre\Object\Customer; -use FireflyIII\Services\Spectre\Object\Token; -use FireflyIII\Services\Spectre\Request\CreateTokenRequest; -use Log; - -/** - * Trait GetSpectreTokenTrait - * - * @codeCoverageIgnore - * @deprecated - */ -trait GetSpectreTokenTrait -{ - /** - * @param ImportJob $importJob - * @param Customer $customer - * - * @return Token - * @throws \FireflyIII\Exceptions\FireflyException - */ - protected function getToken(ImportJob $importJob, Customer $customer): Token - { - Log::debug('Now in GetSpectreTokenTrait::ChooseLoginsHandler::getToken()'); - /** @var CreateTokenRequest $request */ - $request = app(CreateTokenRequest::class); - $request->setUser($importJob->user); - $request->setUri(route('import.job.status.index', [$importJob->key])); - $request->setCustomer($customer); - $request->call(); - Log::debug('Call to get token is finished'); - - return $request->getToken(); - } -} diff --git a/app/Support/Import/JobConfiguration/Bunq/BunqJobConfigurationInterface.php b/app/Support/Import/JobConfiguration/Bunq/BunqJobConfigurationInterface.php deleted file mode 100644 index d662694c86..0000000000 --- a/app/Support/Import/JobConfiguration/Bunq/BunqJobConfigurationInterface.php +++ /dev/null @@ -1,74 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Bunq; - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; - -/** - * Interface BunqJobConfigurationInterface - * @deprecated - * @codeCoverageIgnore - */ -interface BunqJobConfigurationInterface -{ - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool; - - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag; - - /** - * Get data for config view. - * - * @return array - */ - public function getNextData(): array; - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string; - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void; - -} diff --git a/app/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandler.php b/app/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandler.php deleted file mode 100644 index 7cf82b10bb..0000000000 --- a/app/Support/Import/JobConfiguration/Bunq/ChooseAccountsHandler.php +++ /dev/null @@ -1,271 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Bunq; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account as AccountModel; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class ChooseAccountsHandler - * @deprecated - * @codeCoverageIgnore - */ -class ChooseAccountsHandler implements BunqJobConfigurationInterface -{ - - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var CurrencyRepositoryInterface */ - private $currencyRepository; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - $config = $this->repository->getConfiguration($this->importJob); - $mapping = $config['mapping'] ?? []; - $complete = count($mapping) > 0; - if (true === $complete) { - // move job to correct stage to download transactions - $this->repository->setStage($this->importJob, 'go-for-import'); - } - - return $complete; - } - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - * @throws FireflyException - */ - public function configureJob(array $data): MessageBag - { - $config = $this->repository->getConfiguration($this->importJob); - $accounts = $config['accounts'] ?? []; - $mapping = $data['account_mapping'] ?? []; - $applyRules = 1 === (int)($data['apply_rules'] ?? 0); - $final = []; - - /* - * $ibanToAsset is used to map bunq IBAN's to Firefly III asset accounts. The array is structured like this: - * 12BUNQ123456.. => 1, - * 12BUNQ928811.. => 4, - * - * And contains the bunq asset account iban (left) and the FF3 asset ID (right). - * - * This is used to properly map transfers. - */ - $ibanToAsset = []; - Log::debug('Going to map IBANs for easy mapping later on.'); - if (0 === count($accounts)) { - throw new FireflyException('No bunq accounts found. Import cannot continue.'); // @codeCoverageIgnore - } - if (0 === count($mapping)) { - $messages = new MessageBag; - $messages->add('nomap', (string)trans('import.bunq_no_mapping')); - - return $messages; - } - foreach ($mapping as $bunqId => $localId) { - $bunqId = (int)$bunqId; - $localId = (int)$localId; - - Log::debug(sprintf('Now trying to link bunq acount #%d with Firefly III account %d', $bunqId, $localId)); - - // validate each - $bunqId = $this->validBunqAccount($bunqId); - $accountId = $this->validLocalAccount($localId); - - Log::debug(sprintf('After validation: bunq account #%d with Firefly III account %d', $bunqId, $localId)); - - $bunqIban = $this->getBunqIban($bunqId); - - Log::debug(sprintf('IBAN for bunq account #%d is "%s"', $bunqId, $bunqIban)); - if (null !== $bunqIban) { - $ibanToAsset[$bunqIban] = $accountId; // @codeCoverageIgnore - } - $final[$bunqId] = $accountId; - } - $config['mapping'] = $final; - $config['bunq-iban'] = $ibanToAsset; - $config['apply-rules'] = $applyRules; - $this->repository->setConfiguration($this->importJob, $config); - - Log::info('Account mapping: ', $final); - Log::info('Bunq IBAN array: ', $ibanToAsset); - - return new MessageBag; - } - - /** - * Get data for config view. - * - * @return array - * @throws FireflyException - */ - public function getNextData(): array - { - $config = $this->repository->getConfiguration($this->importJob); - $accounts = $config['accounts'] ?? []; - if (0 === count($accounts)) { - throw new FireflyException('No bunq accounts found. Import cannot continue.'); // @codeCoverageIgnore - } - // list the users accounts: - $collection = $this->accountRepository->getAccountsByType([AccountType::ASSET]); - - $localAccounts = []; - /** @var AccountModel $localAccount */ - foreach ($collection as $localAccount) { - $accountId = $localAccount->id; - // TODO we can use getAccountCurrency() instead - $currencyId = (int)$this->accountRepository->getMetaValue($localAccount, 'currency_id'); - $currency = $this->getCurrency($currencyId); - $localAccounts[$accountId] = [ - 'name' => $localAccount->name, - 'iban' => $localAccount->iban, - 'code' => $currency->code, - ]; - } - - return [ - 'accounts' => $accounts, - 'local_accounts' => $localAccounts, - ]; - } - - /** - * @codeCoverageIgnore - * - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - return 'import.bunq.choose-accounts'; - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->currencyRepository = app(CurrencyRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->currencyRepository->setUser($importJob->user); - $this->accountRepository->setUser($importJob->user); - } - - /** - * @param int $bunqId - * - * @return null|string - */ - private function getBunqIban(int $bunqId): ?string - { - $config = $this->repository->getConfiguration($this->importJob); - $accounts = $config['accounts'] ?? []; - /** @var array $bunqAccount */ - foreach ($accounts as $bunqAccount) { - if ((int)$bunqAccount['id'] === $bunqId) { - return $bunqAccount['iban'] ?? null; - } - } - - return null; - } - - /** - * @param int $currencyId - * - * @return TransactionCurrency - */ - private function getCurrency(int $currencyId): TransactionCurrency - { - $currency = $this->currencyRepository->findNull($currencyId); - if (null === $currency) { - return app('amount')->getDefaultCurrencyByUser($this->importJob->user); - } - - return $currency; - - } - - /** - * @param int $bunqId - * - * @return int - */ - private function validBunqAccount(int $bunqId): int - { - $config = $this->repository->getConfiguration($this->importJob); - $accounts = $config['accounts'] ?? []; - /** @var array $bunqAccount */ - foreach ($accounts as $bunqAccount) { - if ((int)$bunqAccount['id'] === $bunqId) { - return $bunqId; - } - } - - return 0; - } - - /** - * @param int $accountId - * - * @return int - */ - private function validLocalAccount(int $accountId): int - { - $account = $this->accountRepository->findNull($accountId); - if (null === $account) { - return 0; - } - - return $accountId; - } -} diff --git a/app/Support/Import/JobConfiguration/Bunq/NewBunqJobHandler.php b/app/Support/Import/JobConfiguration/Bunq/NewBunqJobHandler.php deleted file mode 100644 index 847da7284d..0000000000 --- a/app/Support/Import/JobConfiguration/Bunq/NewBunqJobHandler.php +++ /dev/null @@ -1,105 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Bunq; - -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class NewBunqJobHandler - * @deprecated - * @codeCoverageIgnore - */ -class NewBunqJobHandler implements BunqJobConfigurationInterface -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - return true; - } - - /** - * @codeCoverageIgnore - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('NewBunqJobHandler::configureJob always returns an empty message bag.'); - - return new MessageBag; - } - - /** - * @codeCoverageIgnore - * Get data for config view. - * - * @return array - */ - public function getNextData(): array - { - Log::debug('NewBunqJobHandler::getNextData always returns an empty array.'); - - return []; - } - - /** - * @codeCoverageIgnore - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - Log::debug('NewBunqJobHandler::getNextView always returns "".'); - - return ''; - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/JobConfiguration/File/ConfigureMappingHandler.php b/app/Support/Import/JobConfiguration/File/ConfigureMappingHandler.php deleted file mode 100644 index 8be440542a..0000000000 --- a/app/Support/Import/JobConfiguration/File/ConfigureMappingHandler.php +++ /dev/null @@ -1,354 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\File; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; -use FireflyIII\Import\Mapper\MapperInterface; -use FireflyIII\Import\Specifics\SpecificInterface; -use FireflyIII\Models\Attachment; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; -use League\Csv\Exception; -use League\Csv\Reader; -use League\Csv\Statement; -use Log; - -/** - * Class ConfigureMappingHandler - * @deprecated - * @codeCoverageIgnore - */ -class ConfigureMappingHandler implements FileConfigurationInterface -{ - /** @var AttachmentHelperInterface */ - private $attachments; - /** @var array */ - private $columnConfig; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Apply the users selected specifics on the current row. - * - * @param array $config - * @param array $row - * - * @return array - */ - public function applySpecifics(array $config, array $row): array - { - // run specifics here: - // and this is the point where the specifix go to work. - $validSpecifics = array_keys(config('csv.import_specifics')); - $specifics = $config['specifics'] ?? []; - $names = array_keys($specifics); - foreach ($names as $name) { - if (!in_array($name, $validSpecifics, true)) { - continue; - } - $class = config(sprintf('csv.import_specifics.%s', $name)); - /** @var SpecificInterface $specific */ - $specific = app($class); - - // it returns the row, possibly modified: - $row = $specific->run($row); - } - - return $row; - } - - /** - * Store data associated with current stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - $config = $this->importJob->configuration; - - if (isset($data['mapping']) && is_array($data['mapping'])) { - foreach ($data['mapping'] as $index => $array) { - $config['column-mapping-config'][$index] = []; - foreach ($array as $value => $mapId) { - $mapId = (int)$mapId; - if (0 !== $mapId) { - $config['column-mapping-config'][$index][(string)$value] = $mapId; - } - } - } - } - $this->repository->setConfiguration($this->importJob, $config); - $this->repository->setStage($this->importJob, 'ready_to_run'); - - return new MessageBag; - } - - /** - * Create the "mapper" class that will eventually return the correct data for the user - * to map against. For example: a list of asset accounts. A list of budgets. A list of tags. - * - * @param string $column - * - * @return MapperInterface - * @throws FireflyException - */ - public function createMapper(string $column): MapperInterface - { - $mapperClass = config('csv.import_roles.' . $column . '.mapper'); - $mapperName = sprintf('FireflyIII\\Import\Mapper\\%s', $mapperClass); - if (!class_exists($mapperName)) { - throw new FireflyException(sprintf('Class "%s" does not exist. Cannot map "%s"', $mapperName, $column)); // @codeCoverageIgnore - } - - return app($mapperName); - } - - /** - * For each column in the configuration of the job, will: - * - validate the role. - * - validate if it can be used for mapping - * - if so, create an entry in $columnConfig - * - * @param array $config - * - * @return array the column configuration. - * @throws FireflyException - */ - public function doColumnConfig(array $config): array - { - /** @var array $requestMapping */ - $requestMapping = $config['column-do-mapping'] ?? []; - $columnConfig = []; - /** - * @var int - * @var bool $mustBeMapped - */ - foreach ($requestMapping as $index => $requested) { - // sanitize column name, so we're sure it's valid. - $column = $this->sanitizeColumnName($config['column-roles'][$index] ?? '_ignore'); - $doMapping = $this->doMapOfColumn($column, $requested); - if ($doMapping) { - // user want to map this column. And this is possible. - $columnConfig[$index] = [ - 'name' => $column, - 'options' => $this->createMapper($column)->getMap(), - 'preProcessMap' => $this->getPreProcessorName($column), - 'values' => [], - ]; - } - } - - return $columnConfig; - } - - /** - * For each $name given, and if the user wants to map the column, will return - * true when the column can also be mapped. - * - * Unmappable columns will always return false. - * Mappable columns will return $requested. - * - * @param string $name - * @param bool $requested - * - * @return bool - */ - public function doMapOfColumn(string $name, bool $requested): bool - { - $canBeMapped = config('csv.import_roles.' . $name . '.mappable'); - - return true === $canBeMapped && true === $requested; - } - - /** - * Get the data necessary to show the configuration screen. - * - * @return array - * @throws FireflyException - */ - public function getNextData(): array - { - $config = $this->importJob->configuration; - $columnConfig = $this->doColumnConfig($config); - - // in order to actually map we also need to read the FULL file. - try { - $reader = $this->getReader(); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - Log::error($e->getMessage()); - throw new FireflyException('Cannot get reader: ' . $e->getMessage()); - } - // @codeCoverageIgnoreEnd - - // get ALL values for the mappable columns from the CSV file: - $columnConfig = $this->getValuesForMapping($reader, $config, $columnConfig); - - return $columnConfig; - } - - /** - * Will return the name of the pre-processor: a special class that will clean up any input that may be found - * in the users input (aka the file uploaded). Only two examples exist at this time: a space or comma separated - * list of tags. - * - * @param string $column - * - * @return string - */ - public function getPreProcessorName(string $column): string - { - $name = ''; - $hasPreProcess = config(sprintf('csv.import_roles.%s.pre-process-map', $column)); - $preProcessClass = config(sprintf('csv.import_roles.%s.pre-process-mapper', $column)); - - if (null !== $hasPreProcess && true === $hasPreProcess && null !== $preProcessClass) { - $name = sprintf('FireflyIII\\Import\\MapperPreProcess\\%s', $preProcessClass); - } - - return $name; - } - - /** - * Return an instance of a CSV file reader so content of the file can be read. - * - * @throws \League\Csv\Exception - */ - public function getReader(): Reader - { - $content = ''; - /** @var Collection $collection */ - $collection = $this->repository->getAttachments($this->importJob); - /** @var Attachment $attachment */ - foreach ($collection as $attachment) { - if ('import_file' === $attachment->filename) { - $content = $this->attachments->getAttachmentContent($attachment); - break; - } - } - $config = $this->repository->getConfiguration($this->importJob); - $reader = Reader::createFromString($content); - $reader->setDelimiter($config['delimiter']); - - return $reader; - } - - /** - * Read the CSV file. For each row, check for each column: - * - * - If it can be mapped. And if so, - * - Run the pre-processor - * - Add the value to the list of "values" that the user must map. - * - * @param Reader $reader - * @param array $config - * @param array $columnConfig - * - * @return array - * @throws FireflyException - * - */ - public function getValuesForMapping(Reader $reader, array $config, array $columnConfig): array - { - $offset = isset($config['has-headers']) && true === $config['has-headers'] ? 1 : 0; - try { - $stmt = (new Statement)->offset($offset); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - throw new FireflyException(sprintf('Could not create reader: %s', $e->getMessage())); - } - // @codeCoverageIgnoreEnd - $results = $stmt->process($reader); - $mappableColumns = array_keys($columnConfig); // the actually columns that can be mapped. - foreach ($results as $lineIndex => $line) { - Log::debug(sprintf('Trying to collect values for line #%d', $lineIndex)); - $line = $this->applySpecifics($config, $line); - - /** @var int $columnIndex */ - foreach ($mappableColumns as $columnIndex) { // this is simply 1, 2, 3, etc. - if (!isset($line[$columnIndex])) { - // don't need to handle this. Continue. - continue; - } - $value = trim($line[$columnIndex]); - if ('' === $value) { - // value is empty, ignore it. - continue; - } - $columnConfig[$columnIndex]['values'][] = $value; - } - } - - // loop array again. This time, do uniqueness. - // and remove arrays that have 0 values. - foreach ($mappableColumns as $columnIndex) { - $columnConfig[$columnIndex]['values'] = array_unique($columnConfig[$columnIndex]['values']); - asort($columnConfig[$columnIndex]['values']); - // if the count of this array is zero, there is nothing to map. - if (0 === count($columnConfig[$columnIndex]['values'])) { - unset($columnConfig[$columnIndex]); // @codeCoverageIgnore - } - } - - return $columnConfig; - } - - /** - * For each given column name, will return either the name (when it's a valid one) - * or return the _ignore column. - * - * @param string $name - * - * @return string - */ - public function sanitizeColumnName(string $name): string - { - /** @var array $validColumns */ - $validColumns = array_keys(config('csv.import_roles')); - if (!in_array($name, $validColumns, true)) { - $name = '_ignore'; - } - - return $name; - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->attachments = app(AttachmentHelperInterface::class); - $this->columnConfig = []; - } -} diff --git a/app/Support/Import/JobConfiguration/File/ConfigureRolesHandler.php b/app/Support/Import/JobConfiguration/File/ConfigureRolesHandler.php deleted file mode 100644 index 9c4bde5e66..0000000000 --- a/app/Support/Import/JobConfiguration/File/ConfigureRolesHandler.php +++ /dev/null @@ -1,415 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\File; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; -use FireflyIII\Import\Specifics\SpecificInterface; -use FireflyIII\Models\Attachment; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; -use League\Csv\Exception; -use League\Csv\Reader; -use League\Csv\Statement; -use Log; - -/** - * Class ConfigureRolesHandler - * @deprecated - * @codeCoverageIgnore - */ -class ConfigureRolesHandler implements FileConfigurationInterface -{ - /** @var AttachmentHelperInterface */ - private $attachments; - /** @var array */ - private $examples; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - /** @var int */ - private $totalColumns; - - /** - * Verifies that the configuration of the job is actually complete, and valid. - * - * @param array $config - * - * @return MessageBag - * - */ - public function configurationComplete(array $config): MessageBag - { - /** @var array $roles */ - $roles = $config['column-roles']; - $assigned = 0; - - // check if data actually contains amount column (foreign amount does not count) - $hasAmount = false; - $hasForeignAmount = false; - $hasForeignCode = false; - foreach ($roles as $role) { - if ('_ignore' !== $role) { - ++$assigned; - } - if (in_array($role, ['amount', 'amount_credit', 'amount_debit', 'amount_negated'])) { - $hasAmount = true; - } - if ('foreign-currency-code' === $role) { - $hasForeignCode = true; - } - if ('amount_foreign' === $role) { - $hasForeignAmount = true; - } - } - - // all assigned and correct foreign info - if ($assigned > 0 && $hasAmount && ($hasForeignCode === $hasForeignAmount)) { - return new MessageBag; - } - if (0 === $assigned || !$hasAmount) { - $message = (string)trans('import.job_config_roles_rwarning'); - $messages = new MessageBag(); - $messages->add('error', $message); - - return $messages; - } - - // warn if has foreign amount but no currency code: - if ($hasForeignAmount && !$hasForeignCode) { - $message = (string)trans('import.job_config_roles_fa_warning'); - $messages = new MessageBag(); - $messages->add('error', $message); - - return $messages; - } - - - return new MessageBag; // @codeCoverageIgnore - } - - /** - * Store data associated with current stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - $config = $this->importJob->configuration; - $count = $config['column-count']; - for ($i = 0; $i < $count; ++$i) { - $role = $data['role'][$i] ?? '_ignore'; - $mapping = (isset($data['map'][$i]) && '1' === $data['map'][$i]); - $config['column-roles'][$i] = $role; - $config['column-do-mapping'][$i] = $mapping; - Log::debug(sprintf('Column %d has been given role %s (mapping: %s)', $i, $role, var_export($mapping, true))); - } - $config = $this->ignoreUnmappableColumns($config); - $messages = $this->configurationComplete($config); - - if (0 === $messages->count()) { - $this->repository->setStage($this->importJob, 'ready_to_run'); - if ($this->isMappingNecessary($config)) { - $this->repository->setStage($this->importJob, 'map'); - } - $this->repository->setConfiguration($this->importJob, $config); - } - - return $messages; - } - - /** - * Extracts example data from a single row and store it in the class. - * - * @param array $line - */ - public function getExampleFromLine(array $line): void - { - foreach ($line as $column => $value) { - $value = trim($value); - if ('' != $value) { - $this->examples[$column][] = $value; - } - } - } - - /** - * @return array - */ - public function getExamples(): array - { - return $this->examples; - } - - /** - * Return a bunch of examples from the CSV file the user has uploaded. - * - * @param Reader $reader - * @param array $config - * - * @throws FireflyException - */ - public function getExamplesFromFile(Reader $reader, array $config): void - { - $limit = (int)config('csv.example_rows', 5); - $offset = isset($config['has-headers']) && true === $config['has-headers'] ? 1 : 0; - - // make statement. - try { - $stmt = (new Statement)->limit($limit)->offset($offset); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - Log::error($e->getMessage()); - throw new FireflyException($e->getMessage()); - } - // @codeCoverageIgnoreEnd - - // grab the records: - $records = $stmt->process($reader); - /** @var array $line */ - foreach ($records as $line) { - $line = array_values($line); - $line = $this->processSpecifics($config, $line); - $count = count($line); - $this->totalColumns = $count > $this->totalColumns ? $count : $this->totalColumns; - $this->getExampleFromLine($line); - } - // save column count: - $this->saveColumCount(); - $this->makeExamplesUnique(); - } - - /** - * Get the header row, if one is present. - * - * @param Reader $reader - * @param array $config - * - * @return array - * @throws FireflyException - */ - public function getHeaders(Reader $reader, array $config): array - { - $headers = []; - if (isset($config['has-headers']) && true === $config['has-headers']) { - try { - $stmt = (new Statement)->limit(1)->offset(0); - $records = $stmt->process($reader); - $headers = $records->fetchOne(); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - Log::error($e->getMessage()); - throw new FireflyException($e->getMessage()); - } - // @codeCoverageIgnoreEnd - Log::debug('Detected file headers:', $headers); - } - - return $headers; - } - - /** - * Get the data necessary to show the configuration screen. - * - * @return array - * @throws FireflyException - */ - public function getNextData(): array - { - try { - $reader = $this->getReader(); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - Log::error($e->getMessage()); - throw new FireflyException($e->getMessage()); - } - // @codeCoverageIgnoreEnd - $configuration = $this->importJob->configuration; - $headers = $this->getHeaders($reader, $configuration); - - // get example rows: - $this->getExamplesFromFile($reader, $configuration); - - return [ - 'examples' => $this->examples, - 'roles' => $this->getRoles(), - 'total' => $this->totalColumns, - 'headers' => $headers, - ]; - } - - /** - * Return an instance of a CSV file reader so content of the file can be read. - * - * @throws \League\Csv\Exception - */ - public function getReader(): Reader - { - $content = ''; - /** @var Collection $collection */ - $collection = $this->repository->getAttachments($this->importJob); - /** @var Attachment $attachment */ - foreach ($collection as $attachment) { - if ('import_file' === $attachment->filename) { - $content = $this->attachments->getAttachmentContent($attachment); - break; - } - } - $config = $this->repository->getConfiguration($this->importJob); - $reader = Reader::createFromString($content); - $reader->setDelimiter($config['delimiter']); - - return $reader; - } - - /** - * Returns all possible roles and translate their name. Then sort them. - * - * @codeCoverageIgnore - * @return array - */ - public function getRoles(): array - { - $roles = []; - foreach (array_keys(config('csv.import_roles')) as $role) { - $roles[$role] = (string)trans('import.column_' . $role); - } - asort($roles); - - return $roles; - } - - /** - * If the user has checked columns that cannot be mapped to any value, this function will - * uncheck them and return the configuration again. - * - * @param array $config - * - * @return array - */ - public function ignoreUnmappableColumns(array $config): array - { - $count = $config['column-count']; - for ($i = 0; $i < $count; ++$i) { - $role = $config['column-roles'][$i] ?? '_ignore'; - $mapping = $config['column-do-mapping'][$i] ?? false; - // if the column can be mapped depends on the config: - $canMap = (bool)config(sprintf('csv.import_roles.%s.mappable', $role)); - $mapping = $mapping && $canMap; - $config['column-do-mapping'][$i] = $mapping; - } - - return $config; - } - - /** - * Returns false when it's not necessary to map values. This saves time and is user friendly - * (will skip to the next screen). - * - * @param array $config - * - * @return bool - */ - public function isMappingNecessary(array $config): bool - { - /** @var array $doMapping */ - $doMapping = $config['column-do-mapping'] ?? []; - $toBeMapped = 0; - foreach ($doMapping as $doMap) { - if (true === $doMap) { - ++$toBeMapped; - } - } - - return !(0 === $toBeMapped); - } - - /** - * Make sure that the examples do not contain double data values. - */ - public function makeExamplesUnique(): void - { - foreach ($this->examples as $index => $values) { - $this->examples[$index] = array_unique($values); - } - } - - /** - * if the user has configured specific fixes to be applied, they must be applied to the example data as well. - * - * @param array $config - * @param array $line - * - * @return array - */ - public function processSpecifics(array $config, array $line): array - { - $validSpecifics = array_keys(config('csv.import_specifics')); - $specifics = $config['specifics'] ?? []; - $names = array_keys($specifics); - foreach ($names as $name) { - if (!in_array($name, $validSpecifics, true)) { - continue; - } - /** @var SpecificInterface $specific */ - $specific = app('FireflyIII\Import\Specifics\\' . $name); - $line = $specific->run($line); - } - - return $line; - - } - - /** - * Save the column count in the job. It's used in a later stage. - * - * @return void - */ - public function saveColumCount(): void - { - $config = $this->importJob->configuration; - $config['column-count'] = $this->totalColumns; - $this->repository->setConfiguration($this->importJob, $config); - } - - /** - * Set job and some start values. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->attachments = app(AttachmentHelperInterface::class); - $this->totalColumns = 0; - $this->examples = []; - } -} diff --git a/app/Support/Import/JobConfiguration/File/ConfigureUploadHandler.php b/app/Support/Import/JobConfiguration/File/ConfigureUploadHandler.php deleted file mode 100644 index 8bd2a610b5..0000000000 --- a/app/Support/Import/JobConfiguration/File/ConfigureUploadHandler.php +++ /dev/null @@ -1,162 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\File; - -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\MessageBag; -use Log; - - -/** - * Class ConfigureUploadHandler - * @deprecated - * @codeCoverageIgnore - */ -class ConfigureUploadHandler implements FileConfigurationInterface -{ - /** @var AccountRepositoryInterface */ - private $accountRepos; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Store data associated with current stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - $config = $this->importJob->configuration; - $complete = true; - - // collect values: - $importId = isset($data['csv_import_account']) ? (int)$data['csv_import_account'] : 0; - $delimiter = (string)$data['csv_delimiter']; - $config['has-headers'] = 1 === (int)($data['has_headers'] ?? 0.0); - $config['date-format'] = (string)$data['date_format']; - $config['delimiter'] = 'tab' === $delimiter ? "\t" : $delimiter; - $config['apply-rules'] = 1 === (int)($data['apply_rules'] ?? 0.0); - $config['specifics'] = $this->getSpecifics($data); - // validate values: - $account = $this->accountRepos->findNull($importId); - - // respond to invalid account: - if (null === $account) { - Log::error('Could not find anything for csv_import_account.', ['id' => $importId]); - $complete = false; - } - if (null !== $account) { - $config['import-account'] = $account->id; - } - - $this->repository->setConfiguration($this->importJob, $config); - if ($complete) { - $this->repository->setStage($this->importJob, 'roles'); - } - if (!$complete) { - $messages = new MessageBag; - $messages->add('account', (string)trans('import.invalid_import_account')); - - return $messages; - } - - return new MessageBag; - } - - /** - * Get the data necessary to show the configuration screen. - * - * @return array - */ - public function getNextData(): array - { - $delimiters = [ - ',' => (string)trans('form.csv_comma'), - ';' => (string)trans('form.csv_semicolon'), - 'tab' => (string)trans('form.csv_tab'), - ]; - $config = $this->importJob->configuration; - $config['date-format'] = $config['date-format'] ?? 'Ymd'; - $specifics = []; - $this->repository->setConfiguration($this->importJob, $config); - - // collect specifics. - foreach (config('csv.import_specifics') as $name => $className) { - $specifics[$name] = [ - 'name' => trans($className::getName()), - 'description' => trans($className::getDescription()), - ]; - } - - $data = [ - 'accounts' => [], - 'delimiters' => $delimiters, - 'specifics' => $specifics, - ]; - - return $data; - } - - /** - * @param array $data - * - * @return array - */ - public function getSpecifics(array $data): array - { - $return = []; - // check if specifics given are correct: - if (isset($data['specifics']) && is_array($data['specifics'])) { - - foreach ($data['specifics'] as $name) { - // verify their content. - $className = sprintf('FireflyIII\\Import\\Specifics\\%s', $name); - if (class_exists($className)) { - $return[$name] = 1; - } - } - } - - return $return; - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->accountRepos = app(AccountRepositoryInterface::class); - $this->accountRepos->setUser($importJob->user); - - } -} diff --git a/app/Support/Import/JobConfiguration/File/FileConfigurationInterface.php b/app/Support/Import/JobConfiguration/File/FileConfigurationInterface.php deleted file mode 100644 index ebde2cfc45..0000000000 --- a/app/Support/Import/JobConfiguration/File/FileConfigurationInterface.php +++ /dev/null @@ -1,55 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\File; - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; - -/** - * Class FileConfigurationInterface. - * @deprecated - * @codeCoverageIgnore - */ -interface FileConfigurationInterface -{ - /** - * Store data associated with current stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag; - - /** - * Get the data necessary to show the configuration screen. - * - * @return array - */ - public function getNextData(): array; - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void; -} diff --git a/app/Support/Import/JobConfiguration/File/NewFileJobHandler.php b/app/Support/Import/JobConfiguration/File/NewFileJobHandler.php deleted file mode 100644 index fe8080df74..0000000000 --- a/app/Support/Import/JobConfiguration/File/NewFileJobHandler.php +++ /dev/null @@ -1,207 +0,0 @@ -. - */ - - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\File; - -use Exception; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; -use FireflyIII\Models\Attachment; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class NewFileJobHandler - * @deprecated - * @codeCoverageIgnore - */ -class NewFileJobHandler implements FileConfigurationInterface -{ - /** @var AttachmentHelperInterface */ - private $attachments; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Store data associated with current stage. - * - * @param array $data - * - * @throws FireflyException - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - // nothing to store, validate upload - // and push to next stage. - $messages = $this->validateAttachments(); - - if ($messages->count() > 0) { - return $messages; - } - - // store config if it's in one of the attachments. - $this->storeConfiguration(); - - // set file type in config: - $config = $this->repository->getConfiguration($this->importJob); - $config['file-type'] = $data['import_file_type']; - $this->repository->setConfiguration($this->importJob, $config); - $this->repository->setStage($this->importJob, 'configure-upload'); - - return new MessageBag(); - - } - - /** - * - * Get the data necessary to show the configuration screen. - * - * @codeCoverageIgnore - * @return array - */ - public function getNextData(): array - { - /** @var array $allowedTypes */ - $allowedTypes = config('import.options.file.import_formats'); - $importFileTypes = []; - $defaultImportType = config('import.options.file.default_import_format'); - foreach ($allowedTypes as $type) { - $importFileTypes[$type] = (string)trans('import.import_file_type_' . $type); - } - - return [ - 'default_type' => $defaultImportType, - 'file_types' => $importFileTypes, - ]; - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->attachments = app(AttachmentHelperInterface::class); - $this->repository->setUser($importJob->user); - } - - /** - * Store config from job. - * - */ - public function storeConfiguration(): void - { - /** @var Collection $attachments */ - $attachments = $this->repository->getAttachments($this->importJob); - /** @var Attachment $attachment */ - foreach ($attachments as $attachment) { - // if file is configuration file, store it into the job. - if ('configuration_file' === $attachment->filename) { - $this->storeConfig($attachment); - } - } - } - - /** - * Check if all attachments are UTF8. - * - * @return MessageBag - * @throws FireflyException - */ - public function validateAttachments(): MessageBag - { - $messages = new MessageBag; - /** @var Collection $attachments */ - $attachments = $this->repository->getAttachments($this->importJob); - /** @var Attachment $attachment */ - foreach ($attachments as $attachment) { - - // check if content is UTF8: - if (!$this->isUTF8($attachment)) { - $message = (string)trans('import.file_not_utf8'); - Log::error($message); - $messages->add('import_file', $message); - // delete attachment: - try { - $attachment->delete(); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - throw new FireflyException(sprintf('Could not delete attachment: %s', $e->getMessage())); - } - - // @codeCoverageIgnoreEnd - - return $messages; - } - - // if file is configuration file, store it into the job. - if ('configuration_file' === $attachment->filename) { - $this->storeConfig($attachment); - } - } - - return $messages; - } - - /** - * @param Attachment $attachment - * - * @return bool - */ - private function isUTF8(Attachment $attachment): bool - { - $content = $this->attachments->getAttachmentContent($attachment); - $result = mb_detect_encoding($content, 'UTF-8', true); - if (false === $result) { - return false; - } - if ('ASCII' !== $result && 'UTF-8' !== $result) { - return false; // @codeCoverageIgnore - } - - return true; - } - - /** - * Take attachment, extract config, and put in job.\ - * - * @param Attachment $attachment - * - */ - private function storeConfig(Attachment $attachment): void - { - $content = $this->attachments->getAttachmentContent($attachment); - $json = json_decode($content, true); - if (null !== $json) { - $this->repository->setConfiguration($this->importJob, $json); - } - } -} diff --git a/app/Support/Import/JobConfiguration/FinTS/ChooseAccountHandler.php b/app/Support/Import/JobConfiguration/FinTS/ChooseAccountHandler.php deleted file mode 100644 index 7e75cfe0e8..0000000000 --- a/app/Support/Import/JobConfiguration/FinTS/ChooseAccountHandler.php +++ /dev/null @@ -1,124 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\FinTS; - - -use Carbon\Carbon; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Import\JobConfiguration\FinTSConfigurationSteps; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\FinTS\FinTS; -use Illuminate\Support\MessageBag; - -/** - * Class ChooseAccountHandler - * - * @codeCoverageIgnore - * @deprecated - */ -class ChooseAccountHandler implements FinTSConfigurationInterface -{ - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Store data associated with current stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - $config = $this->repository->getConfiguration($this->importJob); - $config['fints_account'] = (string)($data['fints_account'] ?? ''); - $config['local_account'] = (string)($data['local_account'] ?? ''); - $config['from_date'] = (string)($data['from_date'] ?? ''); - $config['to_date'] = (string)($data['to_date'] ?? ''); - $this->repository->setConfiguration($this->importJob, $config); - - try { - $finTS = app(FinTS::class, ['config' => $config]); - $finTS->getAccount($config['fints_account']); - } catch (FireflyException $e) { - return new MessageBag([$e->getMessage()]); - } - - $this->repository->setStage($this->importJob, FinTSConfigurationSteps::GO_FOR_IMPORT); - - return new MessageBag(); - } - - /** - * Get the data necessary to show the configuration screen. - * - * @return array - */ - public function getNextData(): array - { - $finTS = app(FinTS::class, ['config' => $this->importJob->configuration]); - $finTSAccounts = $finTS->getAccounts(); - $finTSAccountsData = []; - foreach ($finTSAccounts as $account) { - $finTSAccountsData[$account->getAccountNumber()] = $account->getIban(); - } - - $localAccounts = []; - foreach ($this->accountRepository->getAccountsByType([AccountType::ASSET]) as $localAccount) { - $display_name = $localAccount->name; - if ($localAccount->iban) { - $display_name .= sprintf(' - %s', $localAccount->iban); - } - $localAccounts[$localAccount->id] = $display_name; - } - - $data = [ - 'fints_accounts' => $finTSAccountsData, - 'fints_account' => $this->importJob->configuration['fints_account'] ?? null, - 'local_accounts' => $localAccounts, - 'local_account' => $this->importJob->configuration['local_account'] ?? null, - 'from_date' => $this->importJob->configuration['from_date'] ?? (new Carbon('now - 1 month'))->format('Y-m-d'), - 'to_date' => $this->importJob->configuration['to_date'] ?? (new Carbon('now'))->format('Y-m-d'), - ]; - - return $data; - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/JobConfiguration/FinTS/FinTSConfigurationInterface.php b/app/Support/Import/JobConfiguration/FinTS/FinTSConfigurationInterface.php deleted file mode 100644 index ef44396f69..0000000000 --- a/app/Support/Import/JobConfiguration/FinTS/FinTSConfigurationInterface.php +++ /dev/null @@ -1,54 +0,0 @@ -. - */ -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\FinTS; - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; - -/** - * @deprecated - * @codeCoverageIgnore - */ -interface FinTSConfigurationInterface -{ - /** - * Store data associated with current stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag; - - /** - * Get the data necessary to show the configuration screen. - * - * @return array - */ - public function getNextData(): array; - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void; -} diff --git a/app/Support/Import/JobConfiguration/FinTS/NewFinTSJobHandler.php b/app/Support/Import/JobConfiguration/FinTS/NewFinTSJobHandler.php deleted file mode 100644 index 67167a61fd..0000000000 --- a/app/Support/Import/JobConfiguration/FinTS/NewFinTSJobHandler.php +++ /dev/null @@ -1,131 +0,0 @@ -. - */ -declare(strict_types=1); - - -namespace FireflyIII\Support\Import\JobConfiguration\FinTS; - - -use FireflyIII\Import\JobConfiguration\FinTSConfigurationSteps; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\FinTS\FinTS; -use Illuminate\Support\Facades\Crypt; -use Illuminate\Support\MessageBag; - -/** - * Class NewFinTSJobHandler - * @codeCoverageIgnore - * @deprecated - */ -class NewFinTSJobHandler implements FinTSConfigurationInterface -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Store data associated with current stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - $config = []; - - $config['fints_url'] = trim($data['fints_url'] ?? ''); - $config['fints_port'] = (int)($data['fints_port'] ?? ''); - $config['fints_bank_code'] = (string)($data['fints_bank_code'] ?? ''); - $config['fints_username'] = (string)($data['fints_username'] ?? ''); - $config['fints_password'] = (string)(Crypt::encrypt($data['fints_password']) ?? ''); // verified - $config['apply-rules'] = 1 === (int)($data['apply_rules'] ?? 0); - - // sanitize FinTS URL. - $config['fints_url'] = $this->validURI($config['fints_url']) ? $config['fints_url'] : ''; - - $this->repository->setConfiguration($this->importJob, $config); - - $incomplete = false; - foreach ($config as $value) { - $incomplete = '' === $value or $incomplete; - } - - if ($incomplete) { - return new MessageBag([trans('import.incomplete_fints_form')]); - } - $finTS = app(FinTS::class, ['config' => $this->importJob->configuration]); - if (true !== ($checkConnection = $finTS->checkConnection())) { - return new MessageBag([trans('import.fints_connection_failed', ['originalError' => $checkConnection])]); - } - - $this->repository->setStage($this->importJob, FinTSConfigurationSteps::CHOOSE_ACCOUNT); - - return new MessageBag(); - } - - /** - * Get the data necessary to show the configuration screen. - * - * @return array - */ - public function getNextData(): array - { - $config = $this->importJob->configuration; - - return [ - 'fints_url' => $config['fints_url'] ?? '', - 'fints_port' => $config['fints_port'] ?? '443', - 'fints_bank_code' => $config['fints_bank_code'] ?? '', - 'fints_username' => $config['fints_username'] ?? '', - ]; - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - - /** - * @param string $fints_url - * - * @return bool - */ - private function validURI(string $fintsUri): bool - { - $res = filter_var($fintsUri, FILTER_VALIDATE_URL); - if (false === $res) { - return false; - } - $scheme = parse_url($fintsUri, PHP_URL_SCHEME); - - return 'https' === $scheme; - } - - -} diff --git a/app/Support/Import/JobConfiguration/Spectre/AuthenticatedHandler.php b/app/Support/Import/JobConfiguration/Spectre/AuthenticatedHandler.php deleted file mode 100644 index 9fe4faf428..0000000000 --- a/app/Support/Import/JobConfiguration/Spectre/AuthenticatedHandler.php +++ /dev/null @@ -1,96 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Spectre; - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; -use Log; - -/** - * @codeCoverageIgnore - * - * Class AuthenticatedHandler - * @deprecated - */ -class AuthenticatedHandler implements SpectreJobConfigurationInterface -{ - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - Log::debug('AuthenticatedConfigHandler::configurationComplete() always returns true'); - - return true; - } - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('AuthenticatedConfigHandler::configureJob() always returns empty message bag'); - - return new MessageBag(); - } - - /** - * Get data for config view. - * - * @return array - */ - public function getNextData(): array - { - Log::debug('AuthenticatedConfigHandler::getNextData() always returns []'); - - return []; - } - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - Log::debug('AuthenticatedConfigHandler::getNextView() always returns ""'); - - return ''; - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - } -} diff --git a/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php b/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php deleted file mode 100644 index 25d57c1ec5..0000000000 --- a/app/Support/Import/JobConfiguration/Spectre/ChooseAccountsHandler.php +++ /dev/null @@ -1,255 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Spectre; - - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account as AccountModel; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Spectre\Object\Account as SpectreAccount; -use FireflyIII\Services\Spectre\Object\Login; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class ChooseAccountsHandler - * @deprecated - * @codeCoverageIgnore - */ -class ChooseAccountsHandler implements SpectreJobConfigurationInterface -{ - - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var CurrencyRepositoryInterface */ - private $currencyRepository; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - Log::debug('Now in ChooseAccountsHandler::configurationComplete()'); - $config = $this->importJob->configuration; - $importAccounts = $config['account_mapping'] ?? []; - $complete = count($importAccounts) > 0 && $importAccounts !== [0 => 0]; - if ($complete) { - Log::debug('Looks like user has mapped import accounts to Firefly III accounts', $importAccounts); - $this->repository->setStage($this->importJob, 'go-for-import'); - } - - return $complete; - } - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('Now in ChooseAccountsHandler::configureJob()', $data); - $config = $this->importJob->configuration; - $mapping = $data['account_mapping'] ?? []; - $final = []; - $applyRules = 1 === (int)($data['apply_rules'] ?? 0); - foreach ($mapping as $spectreId => $localId) { - // validate each - $spectreId = $this->validSpectreAccount((int)$spectreId); - $accountId = $this->validLocalAccount((int)$localId); - $final[$spectreId] = $accountId; - - } - Log::debug('Final mapping is:', $final); - $messages = new MessageBag; - $config['account_mapping'] = $final; - $config['apply-rules'] = $applyRules; - $this->repository->setConfiguration($this->importJob, $config); - if ($final === [0 => 0] || 0 === count($final)) { - $messages->add('count', (string)trans('import.spectre_no_mapping')); - } - - return $messages; - } - - /** - * Get data for config view. - * - * @return array - * @throws FireflyException - * - */ - public function getNextData(): array - { - Log::debug('Now in ChooseAccountsHandler::getnextData()'); - $config = $this->importJob->configuration; - $accounts = $config['accounts'] ?? []; - if (0 === count($accounts)) { - throw new FireflyException('It seems you have no accounts with this bank. The import cannot continue.'); // @codeCoverageIgnore - } - $converted = []; - foreach ($accounts as $accountArray) { - $converted[] = new SpectreAccount($accountArray); - } - - // get the provider that was used. - $login = null; - $logins = $config['all-logins'] ?? []; - $selected = $config['selected-login'] ?? 0; - if (0 === count($logins)) { - throw new FireflyException('It seems you have no configured logins in this import job. The import cannot continue.'); // @codeCoverageIgnore - } - Log::debug(sprintf('Selected login to use is %d', $selected)); - if (0 === $selected) { - $login = new Login($logins[0]); - Log::debug(sprintf('Will use login %d (%s %s)', $login->getId(), $login->getProviderName(), $login->getCountryCode())); - } - if (0 !== $selected) { - foreach ($logins as $loginArray) { - $loginId = $loginArray['id'] ?? -1; - if ($loginId === $selected) { - $login = new Login($loginArray); - Log::debug(sprintf('Will use login %d (%s %s)', $login->getId(), $login->getProviderName(), $login->getCountryCode())); - } - } - } - if (null === $login) { - throw new FireflyException('Was not able to determine which login to use. The import cannot continue.'); // @codeCoverageIgnore - } - - // list the users accounts: - $accounts = $this->accountRepository->getAccountsByType([AccountType::ASSET, AccountType::DEBT, AccountType::LOAN, AccountType::MORTGAGE]); - - $array = []; - /** @var AccountModel $account */ - foreach ($accounts as $account) { - $accountId = $account->id; - // TODO we can use getAccountCurrency() instead - $currencyId = (int)$this->accountRepository->getMetaValue($account, 'currency_id'); - $currency = $this->getCurrency($currencyId); - $array[$accountId] = [ - 'name' => $account->name, - 'iban' => $account->iban, - 'code' => $currency->code, - ]; - } - - return [ - 'accounts' => $converted, - 'ff_accounts' => $array, - 'login' => $login, - - ]; - } - - /** - * @codeCoverageIgnore - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - return 'import.spectre.accounts'; - } - - /** - * @codeCoverageIgnore - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->currencyRepository = app(CurrencyRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->currencyRepository->setUser($importJob->user); - $this->accountRepository->setUser($importJob->user); - } - - /** - * @param int $currencyId - * - * @return TransactionCurrency - */ - private function getCurrency(int $currencyId): TransactionCurrency - { - $currency = $this->currencyRepository->findNull($currencyId); - if (null === $currency) { - return app('amount')->getDefaultCurrencyByUser($this->importJob->user); - } - - return $currency; - - } - - /** - * @param int $accountId - * - * @return int - */ - private function validLocalAccount(int $accountId): int - { - $account = $this->accountRepository->findNull($accountId); - if (null === $account) { - return 0; - } - - return $accountId; - } - - /** - * @param int $accountId - * - * @return int - */ - private function validSpectreAccount(int $accountId): int - { - $config = $this->importJob->configuration; - $accounts = $config['accounts'] ?? []; - foreach ($accounts as $account) { - if ((int)$account['id'] === $accountId) { - return $accountId; - } - } - - return 0; - } -} diff --git a/app/Support/Import/JobConfiguration/Spectre/ChooseLoginHandler.php b/app/Support/Import/JobConfiguration/Spectre/ChooseLoginHandler.php deleted file mode 100644 index e42fe7a0f7..0000000000 --- a/app/Support/Import/JobConfiguration/Spectre/ChooseLoginHandler.php +++ /dev/null @@ -1,146 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Spectre; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Spectre\Object\Login; -use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait; -use FireflyIII\Support\Import\Information\GetSpectreTokenTrait; -use Illuminate\Support\MessageBag; -use Log; - - -/** - * Class ChooseLoginHandler - * @deprecated - * @codeCoverageIgnore - */ -class ChooseLoginHandler implements SpectreJobConfigurationInterface -{ - use GetSpectreCustomerTrait, GetSpectreTokenTrait; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - Log::debug('Now in ChooseLoginHandler::configurationComplete()'); - $config = $this->importJob->configuration; - if (isset($config['selected-login'])) { - Log::debug('config[selected-login] is set, return true.'); - - return true; - } - Log::debug('config[selected-login] is not set, return false.'); - - return false; - } - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - * @throws FireflyException - */ - public function configureJob(array $data): MessageBag - { - Log::debug('Now in ChooseLoginHandler::configureJob()'); - $selectedLogin = (int)($data['spectre_login_id'] ?? 0.0); - $config = $this->importJob->configuration; - $config['selected-login'] = $selectedLogin; - $this->repository->setConfiguration($this->importJob, $config); - Log::debug(sprintf('The selected login by the user is #%d', $selectedLogin)); - - // if selected login is zero, create a new one. - if (0 === $selectedLogin) { - Log::debug('Login is zero, get Spectre customer + token and store it in config.'); - $customer = $this->getCustomer($this->importJob); - // get a token for the user and redirect to next stage - $token = $this->getToken($this->importJob, $customer); - $config['customer'] = $customer->toArray(); - $config['token'] = $token->toArray(); - $this->repository->setConfiguration($this->importJob, $config); - // move job to correct stage to redirect to Spectre: - $this->repository->setStage($this->importJob, 'do-authenticate'); - - return new MessageBag; - - } - $this->repository->setStage($this->importJob, 'authenticated'); - - return new MessageBag; - } - - /** - * Get data for config view. - * - * @return array - */ - public function getNextData(): array - { - Log::debug('Now in ChooseLoginHandler::getNextData()'); - $config = $this->importJob->configuration; - $data = ['logins' => []]; - $logins = $config['all-logins'] ?? []; - Log::debug(sprintf('Count of logins in configuration is %d.', count($logins))); - foreach ($logins as $login) { - $data['logins'][] = new Login($login); - } - - return $data; - } - - /** - * @codeCoverageIgnore - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - return 'import.spectre.choose-login'; - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandler.php b/app/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandler.php deleted file mode 100644 index ab0f441dd6..0000000000 --- a/app/Support/Import/JobConfiguration/Spectre/DoAuthenticateHandler.php +++ /dev/null @@ -1,130 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Spectre; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Spectre\Object\Token; -use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait; -use FireflyIII\Support\Import\Information\GetSpectreTokenTrait; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class AuthenticateConfig - * @deprecated - * @codeCoverageIgnore - */ -class DoAuthenticateHandler implements SpectreJobConfigurationInterface -{ - use GetSpectreTokenTrait, GetSpectreCustomerTrait; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * @codeCoverageIgnore - * Return true when this stage is complete. - * - * always returns false. - * - * @return bool - */ - public function configurationComplete(): bool - { - Log::debug('DoAuthenticateHandler::configurationComplete() will always return false'); - - return false; - } - - /** - * @codeCoverageIgnore - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('DoAuthenticateHandler::configureJob() will do nothing.'); - - return new MessageBag; - } - - /** - * Get data for config view. - * - * @return array - * @throws FireflyException - */ - public function getNextData(): array - { - Log::debug('Now in DoAuthenticateHandler::getNextData()'); - - // getNextData() only makes sure the job is ready for the next stage. - $this->repository->setStatus($this->importJob, 'ready_to_run'); - $this->repository->setStage($this->importJob, 'authenticated'); - - // get token from configuration: - $config = $this->importJob->configuration; - $token = isset($config['token']) ? new Token($config['token']) : null; - - if (null === $token) { - // get a new one from Spectre: - Log::debug('No existing token, get a new one.'); - // get a new token from Spectre. - $customer = $this->getCustomer($this->importJob); - $token = $this->getToken($this->importJob, $customer); - } - - return ['token-url' => $token->getConnectUrl()]; - } - - /** - * @codeCoverageIgnore - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - return 'import.spectre.redirect'; - } - - /** - * @codeCoverageIgnore - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/JobConfiguration/Spectre/NewSpectreJobHandler.php b/app/Support/Import/JobConfiguration/Spectre/NewSpectreJobHandler.php deleted file mode 100644 index b90c8e8007..0000000000 --- a/app/Support/Import/JobConfiguration/Spectre/NewSpectreJobHandler.php +++ /dev/null @@ -1,98 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Spectre; - - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; -use Log; - -/** - * @codeCoverageIgnore - * - * Class NewSpectreJobHandler - * @deprecated - */ -class NewSpectreJobHandler implements SpectreJobConfigurationInterface -{ - - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - Log::debug('NewSpectreJobHandler::configurationComplete() always returns true'); - - return true; - } - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('NewSpectreJobHandler::configureJob() always returns an empty message bag'); - - return new MessageBag; - } - - /** - * Get data for config view. - * - * @return array - */ - public function getNextData(): array - { - Log::debug('NewSpectreJobHandler::getNextData() always returns []'); - - return []; - } - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - Log::debug('NewSpectreJobHandler::getNextView() always returns ""'); - - return ''; - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - } -} diff --git a/app/Support/Import/JobConfiguration/Spectre/SpectreJobConfigurationInterface.php b/app/Support/Import/JobConfiguration/Spectre/SpectreJobConfigurationInterface.php deleted file mode 100644 index dc7846b0dd..0000000000 --- a/app/Support/Import/JobConfiguration/Spectre/SpectreJobConfigurationInterface.php +++ /dev/null @@ -1,75 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Spectre; - - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; - -/** - * Interface SpectreJobConfigurationInterface - * @deprecated - * @codeCoverageIgnore - */ -interface SpectreJobConfigurationInterface -{ - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool; - - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag; - - /** - * Get data for config view. - * - * @return array - */ - public function getNextData(): array; - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string; - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void; - -} diff --git a/app/Support/Import/JobConfiguration/Ynab/NewYnabJobHandler.php b/app/Support/Import/JobConfiguration/Ynab/NewYnabJobHandler.php deleted file mode 100644 index 0b6cb4701a..0000000000 --- a/app/Support/Import/JobConfiguration/Ynab/NewYnabJobHandler.php +++ /dev/null @@ -1,260 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Ynab; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\GuzzleException; -use Illuminate\Support\MessageBag; -use Log; -use RuntimeException; - -/** - * Class NewYnabJobHandler - * @deprecated - * @codeCoverageIgnore - */ -class NewYnabJobHandler implements YnabJobConfigurationInterface -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Return true when this stage is complete. - * - * @return bool - * @throws FireflyException - */ - public function configurationComplete(): bool - { - if (!$this->hasRefreshToken()) { - Log::debug('YNAB NewYnabJobHandler configurationComplete: stage is new, no refresh token, return false'); - - return false; - } - if ($this->hasRefreshToken() && $this->hasClientId() && $this->hasClientSecret()) { - Log::debug('YNAB NewYnabJobHandler configurationComplete: stage is new, has a refresh token, return true'); - // need to grab access token using refresh token - $this->getAccessToken(); - $this->repository->setStatus($this->importJob, 'ready_to_run'); - $this->repository->setStage($this->importJob, 'get_budgets'); - - return true; - } - Log::error('YNAB NewYnabJobHandler configurationComplete: something broke, return true'); - - return true; - } - - /** - * Store the job configuration. There is never anything to store for this stage. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('YNAB NewYnabJobHandler configureJob: nothing to do.'); - - return new MessageBag; - } - - /** - * Get data for config view. - * - * @return array - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \Psr\Container\ContainerExceptionInterface - */ - public function getNextData(): array - { - $data = []; - // here we update the job so it can redirect properly to YNAB - if (!$this->hasRefreshToken() && $this->hasClientSecret() && $this->hasClientId()) { - // update stage to make sure we catch the token. - $this->repository->setStage($this->importJob, 'catch-auth-code'); - $clientId = app('preferences')->get('ynab_client_id')->data; - $callBackUri = route('import.callback.ynab'); - $uri = sprintf( - 'https://app.youneedabudget.com/oauth/authorize?client_id=%s&redirect_uri=%s&response_type=code&state=%s', $clientId, $callBackUri, - $this->importJob->key - ); - $data['token-url'] = $uri; - Log::debug(sprintf('YNAB getNextData: URI to redirect to is %s', $uri)); - } - - return $data; - } - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - Log::debug('Return YNAB redirect view.'); - - return 'import.ynab.redirect'; - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - - - /** - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \Psr\Container\ContainerExceptionInterface - * @throws FireflyException - */ - private function getAccessToken(): void - { - $clientId = app('preferences')->get('ynab_client_id')->data; - $clientSecret = app('preferences')->get('ynab_client_secret')->data; - $refreshToken = app('preferences')->get('ynab_refresh_token')->data; - $uri = sprintf( - 'https://app.youneedabudget.com/oauth/token?client_id=%s&client_secret=%s&grant_type=refresh_token&refresh_token=%s', $clientId, $clientSecret, - $refreshToken - ); - - $client = new Client(); - try { - $res = $client->request('post', $uri); - } catch (GuzzleException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - throw new FireflyException($e->getMessage()); - } - $statusCode = $res->getStatusCode(); - try { - $content = trim($res->getBody()->getContents()); - } catch (RuntimeException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - throw new FireflyException($e->getMessage()); - } - $json = json_decode($content, true) ?? []; - Log::debug(sprintf('Status code from YNAB is %d', $statusCode)); - Log::debug(sprintf('Body of result is %s', $content), $json); - - // store refresh token (if present?) as preference - // store token in job: - $configuration = $this->repository->getConfiguration($this->importJob); - $configuration['access_token'] = $json['access_token']; - $configuration['access_token_expires'] = (int)$json['created_at'] + (int)$json['expires_in']; - $this->repository->setConfiguration($this->importJob, $configuration); - - // also store new refresh token: - $refreshToken = (string)($json['refresh_token'] ?? ''); - if ('' !== $refreshToken) { - app('preferences')->set('ynab_refresh_token', $refreshToken); - } - - - Log::debug('end of NewYnabJobHandler::getAccessToken()'); - } - - /** - * Check if we have the client ID. - * - * @return bool - */ - private function hasClientId(): bool - { - $clientId = app('preferences')->getForUser($this->importJob->user, 'ynab_client_id', null); - if (null === $clientId) { - Log::debug('user has no YNAB client ID'); - - return false; - } - if ('' === (string)$clientId->data) { - Log::debug('user has no YNAB client ID (empty)'); - - return false; - } - Log::debug('user has a YNAB client ID'); - - return true; - } - - /** - * Check if we have the client secret - * - * @return bool - */ - private function hasClientSecret(): bool - { - $clientSecret = app('preferences')->getForUser($this->importJob->user, 'ynab_client_secret', null); - if (null === $clientSecret) { - Log::debug('user has no YNAB client secret'); - - return false; - } - if ('' === (string)$clientSecret->data) { - Log::debug('user has no YNAB client secret (empty)'); - - return false; - } - Log::debug('user has a YNAB client secret'); - - return true; - } - - /** - * @return bool - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \Psr\Container\ContainerExceptionInterface - */ - private function hasRefreshToken(): bool - { - $preference = app('preferences')->get('ynab_refresh_token'); - if (null === $preference) { - Log::debug('user has no YNAB refresh token.'); - - return false; - } - if ('' === (string)$preference->data) { - Log::debug('user has no YNAB refresh token (empty).'); - - return false; - } - Log::debug(sprintf('user has YNAB refresh token: %s', $preference->data)); - - return true; - } -} diff --git a/app/Support/Import/JobConfiguration/Ynab/SelectAccountsHandler.php b/app/Support/Import/JobConfiguration/Ynab/SelectAccountsHandler.php deleted file mode 100644 index dcadd72390..0000000000 --- a/app/Support/Import/JobConfiguration/Ynab/SelectAccountsHandler.php +++ /dev/null @@ -1,241 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Ynab; - - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class SelectAccountsHandler - * @deprecated - * @codeCoverageIgnore - */ -class SelectAccountsHandler implements YnabJobConfigurationInterface -{ - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var CurrencyRepositoryInterface */ - private $currencyRepository; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - Log::debug('Now in SelectAccountsHandler::configurationComplete()'); - $config = $this->importJob->configuration; - $mapping = $config['mapping'] ?? []; - if (count($mapping) > 0) { - // mapping is complete. - Log::debug('Looks like user has mapped YNAB accounts to Firefly III accounts', $mapping); - $this->repository->setStage($this->importJob, 'go-for-import'); - - return true; - } - - return false; - } - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('Now in SelectAccountsHandler::configureJob()', $data); - $config = $this->importJob->configuration; - $mapping = $data['account_mapping'] ?? []; - $final = []; - $applyRules = 1 === (int)($data['apply_rules'] ?? 0); - foreach ($mapping as $ynabId => $localId) { - // validate each - $ynabId = $this->validYnabAccount($ynabId); - $accountId = $this->validLocalAccount((int)$localId); - if (0 !== $accountId) { - $final[$ynabId] = $accountId; - } - } - Log::debug('Final mapping is:', $final); - $messages = new MessageBag; - $config['mapping'] = $final; - $config['apply-rules'] = $applyRules; - $this->repository->setConfiguration($this->importJob, $config); - if ($final === ['' => 0] || 0 === count($final)) { - $messages->add('count', (string)trans('import.ynab_no_mapping')); - } - - return $messages; - } - - /** - * Get data for config view. - * - * @return array - * @throws FireflyException - */ - public function getNextData(): array - { - - Log::debug('Now in ChooseAccountsHandler::getnextData()'); - $config = $this->importJob->configuration; - $ynabAccounts = $config['accounts'] ?? []; - $budget = $this->getSelectedBudget(); - if (0 === count($ynabAccounts)) { - throw new FireflyException('It seems you have no accounts with this budget. The import cannot continue.'); // @codeCoverageIgnore - } - // list the users accounts: - $ffAccounts = $this->accountRepository->getAccountsByType([AccountType::ASSET]); - - $array = []; - /** @var Account $account */ - foreach ($ffAccounts as $account) { - $accountId = $account->id; - // TODO we can use getAccountCurrency() instead - $currencyId = (int)$this->accountRepository->getMetaValue($account, 'currency_id'); - $currency = $this->getCurrency($currencyId); - $array[$accountId] = [ - 'name' => $account->name, - 'iban' => $account->iban, - 'code' => $currency->code, - ]; - } - - return [ - 'budget' => $budget, - 'ynab_accounts' => $ynabAccounts, - 'ff_accounts' => $array, - ]; - } - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - return 'import.ynab.accounts'; - } - - /** - * @codeCoverageIgnore - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->currencyRepository = app(CurrencyRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->currencyRepository->setUser($importJob->user); - $this->accountRepository->setUser($importJob->user); - } - - /** - * @param int $currencyId - * - * @return TransactionCurrency - */ - private function getCurrency(int $currencyId): TransactionCurrency - { - $currency = $this->currencyRepository->findNull($currencyId); - if (null === $currency) { - return app('amount')->getDefaultCurrencyByUser($this->importJob->user); - } - - return $currency; - - } - - /** - * @return array - */ - private function getSelectedBudget(): array - { - $config = $this->repository->getConfiguration($this->importJob); - $budgets = $config['budgets'] ?? []; - $selected = $config['selected_budget'] ?? ''; - foreach ($budgets as $budget) { - if ($budget['id'] === $selected) { - return $budget; - } - } - - return $budgets[0] ?? []; - } - - /** - * @param int $accountId - * - * @return int - */ - private function validLocalAccount(int $accountId): int - { - $account = $this->accountRepository->findNull($accountId); - if (null === $account) { - return 0; - } - - return $accountId; - } - - /** - * @param string $accountId - * - * @return string - */ - private function validYnabAccount(string $accountId): string - { - $config = $this->importJob->configuration; - $accounts = $config['accounts'] ?? []; - foreach ($accounts as $account) { - if ($account['id'] === $accountId) { - return $accountId; - } - } - - return ''; - } -} diff --git a/app/Support/Import/JobConfiguration/Ynab/SelectBudgetHandler.php b/app/Support/Import/JobConfiguration/Ynab/SelectBudgetHandler.php deleted file mode 100644 index 9a2790d270..0000000000 --- a/app/Support/Import/JobConfiguration/Ynab/SelectBudgetHandler.php +++ /dev/null @@ -1,187 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Ynab; - -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Illuminate\Support\Collection; -use Illuminate\Support\MessageBag; -use Log; - -/** - * Class SelectBudgetHandler - * @deprecated - * @codeCoverageIgnore - */ -class SelectBudgetHandler implements YnabJobConfigurationInterface -{ - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var Collection */ - private $accounts; - /** @var CurrencyRepositoryInterface */ - private $currencyRepository; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool - { - Log::debug('Now in SelectBudgetHandler::configComplete'); - $configuration = $this->repository->getConfiguration($this->importJob); - $selectedBudget = $configuration['selected_budget'] ?? ''; - if ('' !== $selectedBudget) { - Log::debug(sprintf('Selected budget is %s, config is complete. Return true.', $selectedBudget)); - $this->repository->setStage($this->importJob, 'get_accounts'); - - return true; - } - Log::debug('User has not selected a budget yet, config is not yet complete.'); - - return false; - } - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag - { - Log::debug('Now in SelectBudgetHandler::configureJob'); - $configuration = $this->repository->getConfiguration($this->importJob); - $configuration['selected_budget'] = $data['budget_id']; - - Log::debug(sprintf('Set selected budget to %s', $data['budget_id'])); - Log::debug('Mark job as ready for next stage.'); - - - $this->repository->setConfiguration($this->importJob, $configuration); - - return new MessageBag; - } - - /** - * Get data for config view. - * - * @return array - */ - public function getNextData(): array - { - Log::debug('Now in SelectBudgetHandler::getNextData'); - $configuration = $this->repository->getConfiguration($this->importJob); - $budgets = $configuration['budgets'] ?? []; - $available = []; - $notAvailable = []; - $total = count($budgets); - foreach ($budgets as $budget) { - if ($this->haveAssetWithCurrency($budget['currency_code'])) { - Log::debug('Add budget to available list.'); - $available[$budget['id']] = $budget['name'] . ' (' . $budget['currency_code'] . ')'; - continue; - } - Log::debug('Add budget to notAvailable list.'); - $notAvailable[$budget['id']] = $budget['name'] . ' (' . $budget['currency_code'] . ')'; - - } - - return [ - 'available' => $available, - 'not_available' => $notAvailable, - 'total' => $total, - ]; - } - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string - { - Log::debug('Now in SelectBudgetHandler::getNextView'); - - return 'import.ynab.select-budgets'; - } - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->currencyRepository = app(CurrencyRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - - $this->repository->setUser($importJob->user); - $this->currencyRepository->setUser($importJob->user); - $this->accountRepository->setUser($importJob->user); - - $this->accounts = $this->accountRepository->getAccountsByType([AccountType::ASSET, AccountType::DEFAULT]); - } - - /** - * @param string $code - * - * @return bool - */ - private function haveAssetWithCurrency(string $code): bool - { - $currency = $this->currencyRepository->findByCodeNull($code); - if (null === $currency) { - Log::debug(sprintf('No currency X found with code "%s"', $code)); - - return false; - } - /** @var Account $account */ - foreach ($this->accounts as $account) { - // TODO we can use getAccountCurrency() instead - $currencyId = (int)$this->accountRepository->getMetaValue($account, 'currency_id'); - Log::debug(sprintf('Currency of %s is %d (looking for %d).', $account->name, $currencyId, $currency->id)); - if ($currencyId === $currency->id) { - Log::debug('Return true!'); - - return true; - } - } - Log::debug('Found nothing, return false.'); - - return false; - } -} diff --git a/app/Support/Import/JobConfiguration/Ynab/YnabJobConfigurationInterface.php b/app/Support/Import/JobConfiguration/Ynab/YnabJobConfigurationInterface.php deleted file mode 100644 index 1752b566e6..0000000000 --- a/app/Support/Import/JobConfiguration/Ynab/YnabJobConfigurationInterface.php +++ /dev/null @@ -1,73 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\JobConfiguration\Ynab; - -use FireflyIII\Models\ImportJob; -use Illuminate\Support\MessageBag; - -/** - * Interface YnabJobConfigurationInterface - * @deprecated - * @codeCoverageIgnore - */ -interface YnabJobConfigurationInterface -{ - /** - * Return true when this stage is complete. - * - * @return bool - */ - public function configurationComplete(): bool; - - - /** - * Store the job configuration. - * - * @param array $data - * - * @return MessageBag - */ - public function configureJob(array $data): MessageBag; - - /** - * Get data for config view. - * - * @return array - */ - public function getNextData(): array; - - /** - * Get the view for this stage. - * - * @return string - */ - public function getNextView(): string; - - /** - * Set the import job. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void; -} diff --git a/app/Support/Import/Placeholder/ColumnValue.php b/app/Support/Import/Placeholder/ColumnValue.php deleted file mode 100644 index 81fd343174..0000000000 --- a/app/Support/Import/Placeholder/ColumnValue.php +++ /dev/null @@ -1,116 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Placeholder; - -/** - * Class ColumnValue - * - * @codeCoverageIgnore - * @deprecated - */ -class ColumnValue -{ - /** @var int */ - private $mappedValue; - /** @var string */ - private $originalRole; - /** @var string */ - private $role; - /** @var string */ - private $value; - - /** - * ColumnValue constructor. - */ - public function __construct() - { - $this->mappedValue = 0; - } - - /** - * @return int - */ - public function getMappedValue(): int - { - return $this->mappedValue; - } - - /** - * @param int $mappedValue - */ - public function setMappedValue(int $mappedValue): void - { - $this->mappedValue = $mappedValue; - } - - /** - * @return string - */ - public function getOriginalRole(): string - { - return $this->originalRole; - } - - /** - * @param string $originalRole - */ - public function setOriginalRole(string $originalRole): void - { - $this->originalRole = $originalRole; - } - - /** - * @return string - */ - public function getRole(): string - { - return $this->role; - } - - /** - * @param string $role - */ - public function setRole(string $role): void - { - $this->role = $role; - } - - /** - * @return string - */ - public function getValue(): string - { - return $this->value; - } - - /** - * @param string $value - */ - public function setValue(string $value): void - { - $this->value = $value; - } - - -} diff --git a/app/Support/Import/Placeholder/ImportTransaction.php b/app/Support/Import/Placeholder/ImportTransaction.php deleted file mode 100644 index 63155ff058..0000000000 --- a/app/Support/Import/Placeholder/ImportTransaction.php +++ /dev/null @@ -1,446 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Placeholder; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Import\Converter\Amount; -use FireflyIII\Import\Converter\AmountCredit; -use FireflyIII\Import\Converter\AmountDebit; -use FireflyIII\Import\Converter\AmountNegated; -use FireflyIII\Import\Converter\ConverterInterface; -use Log; - -/** - * Class ImportTransaction - * @codeCoverageIgnore - * @deprecated - */ -class ImportTransaction -{ - /** @var string */ - public $accountBic; - /** @var string */ - public $accountIban; - /** @var int */ - public $accountId; - /** @var string */ - public $accountName; - /** @var string */ - public $accountNumber; - /** @var string */ - public $amount; - /** @var string */ - public $amountCredit; - /** @var string */ - public $amountDebit; - /** @var string */ - public $amountNegated; - /** @var int */ - public $billId; - /** @var string */ - public $billName; - /** @var int */ - public $budgetId; - /** @var string */ - public $budgetName; - /** @var int */ - public $categoryId; - /** @var string */ - public $categoryName; - /** @var string */ - public $currencyCode; - /** @var int */ - public $currencyId; - /** @var string */ - public $currencyName; - /** @var string */ - public $currencySymbol; - /** @var string */ - public $date; - /** @var string */ - public $description; - /** @var string */ - public $externalId; - /** @var string */ - public $foreignAmount; - /** @var string */ - public $foreignCurrencyCode; - /** @var int */ - public $foreignCurrencyId; - /** @var array */ - public $meta; - /** @var array */ - public $modifiers; - /** @var string */ - public $note; - /** @var string */ - public $opposingBic; - /** @var string */ - public $opposingIban; - /** @var int */ - public $opposingId; - /** @var string */ - public $opposingName; - /** @var string */ - public $opposingNumber; - /** @var array */ - public $tags; - - /** - * ImportTransaction constructor. - */ - public function __construct() - { - $this->tags = []; - $this->modifiers = []; - $this->meta = []; - $this->description = ''; - $this->note = ''; - - // mappable items, set to 0: - $this->accountId = 0; - $this->budgetId = 0; - $this->billId = 0; - $this->currencyId = 0; - $this->categoryId = 0; - $this->foreignCurrencyId = 0; - $this->opposingId = 0; - - } - - /** - * @param ColumnValue $columnValue - * - * @throws FireflyException - * - */ - public function addColumnValue(ColumnValue $columnValue): void - { - $role = $columnValue->getRole(); - $basics = [ - 'account-iban' => 'accountIban', - 'account-name' => 'accountName', - 'account-bic' => 'accountBic', - 'account-number' => 'accountNumber', - 'amount_debit' => 'amountDebit', - 'amount_credit' => 'amountCredit', - 'amount_negated' => 'amountNegated', - 'amount' => 'amount', - 'amount_foreign' => 'foreignAmount', - 'bill-name' => 'billName', - 'budget-name' => 'budgetName', - 'category-name' => 'categoryName', - 'currency-name' => 'currencyName', - 'currency-code' => 'currencyCode', - 'currency-symbol' => 'currencySymbol', - 'external-id' => 'externalId', - 'foreign-currency-code' => 'foreignCurrencyCode', - 'date-transaction' => 'date', - 'opposing-iban' => 'opposingIban', - 'opposing-name' => 'opposingName', - 'opposing-bic' => 'opposingBic', - 'opposing-number' => 'opposingNumber', - ]; - - $replaceOldRoles = [ - 'original-source' => 'original_source', - 'sepa-cc' => 'sepa_cc', - 'sepa-ct-op' => 'sepa_ct_op', - 'sepa-ct-id' => 'sepa_ct_id', - 'sepa-db' => 'sepa_db', - 'sepa-country' => 'sepa_country', - 'sepa-ep' => 'sepa_ep', - 'sepa-ci' => 'sepa_ci', - 'sepa-batch-id' => 'sepa_batch_id', - 'internal-reference' => 'internal_reference', - 'date-interest' => 'date_interest', - 'date-invoice' => 'date_invoice', - 'date-book' => 'date_book', - 'date-payment' => 'date_payment', - 'date-process' => 'date_process', - 'date-due' => 'date_due', - ]; - if (array_key_exists($role, $replaceOldRoles)) { - $role = $replaceOldRoles[$role]; - } - - if (isset($basics[$role])) { - $field = $basics[$role]; - $this->$field = $columnValue->getValue(); - - return; - } - - $mapped = [ - 'account-id' => 'accountId', - 'bill-id' => 'billId', - 'budget-id' => 'budgetId', - 'category-id' => 'categoryId', - 'currency-id' => 'currencyId', - 'foreign-currency-id' => 'foreignCurrencyId', - 'opposing-id' => 'opposingId', - ]; - if (isset($mapped[$role])) { - $field = $mapped[$role]; - $mappedValue = $this->getMappedValue($columnValue); - $this->$field = $mappedValue; - Log::debug(sprintf('Going to set the %s. Original value is "%s", mapped value is "%s".', $role, $columnValue->getValue(), $mappedValue)); - - return; - } - - $meta = ['sepa_ct_id', 'sepa_ct_op', 'sepa_db', 'sepa_cc', 'sepa_country', 'sepa_batch_id', 'sepa_ep', 'sepa_ci', 'internal_reference', 'date_interest', - 'date_invoice', 'date_book', 'date_payment', 'date_process', 'date_due', 'original_source']; - Log::debug(sprintf('Now going to check role "%s".', $role)); - if (in_array($role, $meta, true)) { - Log::debug(sprintf('Role "%s" is in allowed meta roles, so store its value "%s".', $role, $columnValue->getValue())); - $this->meta[$role] = $columnValue->getValue(); - - return; - } - - $modifiers = ['generic-debit-credit', 'ing-debit-credit', 'rabo-debit-credit']; - if (in_array($role, $modifiers, true)) { - $this->modifiers[$role] = $columnValue->getValue(); - - return; - } - - switch ($role) { - default: - // @codeCoverageIgnoreStart - throw new FireflyException( - sprintf('ImportTransaction cannot handle role "%s" with value "%s"', $role, $columnValue->getValue()) - ); - // @codeCoverageIgnoreEnd - case 'description': - $this->description = trim($this->description . ' ' . $columnValue->getValue()); - break; - case 'note': - $this->note = trim($this->note . ' ' . $columnValue->getValue()); - break; - case 'tags-comma': - $tags = explode(',', $columnValue->getValue()); - $this->tags = array_unique(array_merge($this->tags, $tags)); - break; - case 'tags-space': - $tags = explode(' ', $columnValue->getValue()); - $this->tags = array_unique(array_merge($this->tags, $tags)); - break; - case '_ignore': - break; - - } - } - - /** - * Calculate the amount of this transaction. - * - * @return string - */ - public function calculateAmount(): string - { - Log::debug('Now in importTransaction->calculateAmount()'); - $info = $this->selectAmountInput(); - $class = $info['class'] ?? ''; - if ('' === $class) { - Log::error('No amount information (conversion class) for this row.'); - - return ''; - } - - Log::debug(sprintf('Converter class is %s', $info['class'])); - /** @var ConverterInterface $amountConverter */ - $amountConverter = app($info['class']); - $result = $amountConverter->convert($info['amount']); - Log::debug(sprintf('First attempt to convert gives "%s"', $result)); - // modify - /** - * @var string $role - * @var string $modifier - */ - foreach ($this->modifiers as $role => $modifier) { - $class = sprintf('FireflyIII\\Import\\Converter\\%s', config(sprintf('csv.import_roles.%s.converter', $role))); - /** @var ConverterInterface $converter */ - $converter = app($class); - Log::debug(sprintf('Now launching converter %s', $class)); - $conversion = $converter->convert($modifier); - if ($conversion === -1) { - $result = app('steam')->negative($result); - } - if (1 === $conversion) { - $result = app('steam')->positive($result); - } - Log::debug(sprintf('convertedAmount after conversion is %s', $result)); - } - - Log::debug(sprintf('After modifiers the result is: "%s"', $result)); - - - return $result; - } - - /** - * The method that calculates the foreign amount isn't nearly as complex,\ - * because Firefly III only supports one foreign amount field. So the foreign amount is there - * or isn't. That's about it. However, if it's there, modifiers will be applied too. - * - * @return string - */ - public function calculateForeignAmount(): string - { - if (null === $this->foreignAmount) { - Log::debug('ImportTransaction holds no foreign amount info.'); - - return ''; - } - /** @var ConverterInterface $amountConverter */ - $amountConverter = app(Amount::class); - $result = $amountConverter->convert($this->foreignAmount); - Log::debug(sprintf('First attempt to convert foreign amount gives "%s"', $result)); - /** - * @var string $role - * @var string $modifier - */ - foreach ($this->modifiers as $role => $modifier) { - $class = sprintf('FireflyIII\\Import\\Converter\\%s', config(sprintf('csv.import_roles.%s.converter', $role))); - /** @var ConverterInterface $converter */ - $converter = app($class); - Log::debug(sprintf('Now launching converter %s', $class)); - $conversion = $converter->convert($modifier); - if ($conversion === -1) { - $result = app('steam')->negative($result); - } - if (1 === $conversion) { - $result = app('steam')->positive($result); - } - Log::debug(sprintf('Foreign amount after conversion is %s', $result)); - } - - Log::debug(sprintf('After modifiers the foreign amount is: "%s"', $result)); - - return $result; - } - - /** - * This array is being used to map the account the user is using. - * - * @codeCoverageIgnore - * @return array - */ - public function getAccountData(): array - { - return [ - 'iban' => $this->accountIban, - 'name' => $this->accountName, - 'number' => $this->accountNumber, - 'bic' => $this->accountBic, - ]; - } - - /** - * @codeCoverageIgnore - * @return array - */ - public function getCurrencyData(): array - { - return [ - 'name' => $this->currencyName, - 'code' => $this->currencyCode, - 'symbol' => $this->currencySymbol, - ]; - } - - /** - * @codeCoverageIgnore - * @return array - */ - public function getForeignCurrencyData(): array - { - return [ - 'code' => $this->foreignCurrencyCode, - ]; - } - - /** - * @codeCoverageIgnore - * @return array - */ - public function getOpposingAccountData(): array - { - return [ - 'iban' => $this->opposingIban, - 'name' => $this->opposingName, - 'number' => $this->opposingNumber, - 'bic' => $this->opposingBic, - ]; - } - - /** - * Returns the mapped value if it exists in the ColumnValue object. - * - * @param ColumnValue $columnValue - * - * @return int - */ - private function getMappedValue(ColumnValue $columnValue): int - { - return $columnValue->getMappedValue() > 0 ? $columnValue->getMappedValue() : (int)$columnValue->getValue(); - } - - /** - * This methods decides which input value to use for the amount calculation. - * - * @return array - */ - private function selectAmountInput(): array - { - $info = []; - $converterClass = ''; - if (null !== $this->amount) { - Log::debug('Amount value is not NULL, assume this is the correct value.'); - $converterClass = Amount::class; - $info['amount'] = $this->amount; - } - if (null !== $this->amountDebit) { - Log::debug('Amount DEBIT value is not NULL, assume this is the correct value (overrules Amount).'); - $converterClass = AmountDebit::class; - $info['amount'] = $this->amountDebit; - } - if (null !== $this->amountCredit) { - Log::debug('Amount CREDIT value is not NULL, assume this is the correct value (overrules Amount and AmountDebit).'); - $converterClass = AmountCredit::class; - $info['amount'] = $this->amountCredit; - } - if (null !== $this->amountNegated) { - Log::debug('Amount NEGATED value is not NULL, assume this is the correct value (overrules Amount and AmountDebit and AmountCredit).'); - $converterClass = AmountNegated::class; - $info['amount'] = $this->amountNegated; - } - $info['class'] = $converterClass; - - return $info; - } - -} diff --git a/app/Support/Import/Routine/Bunq/PaymentConverter.php b/app/Support/Import/Routine/Bunq/PaymentConverter.php deleted file mode 100644 index b40363c7a3..0000000000 --- a/app/Support/Import/Routine/Bunq/PaymentConverter.php +++ /dev/null @@ -1,251 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Bunq; - -use bunq\Model\Generated\Endpoint\Payment as BunqPayment; -use bunq\Model\Generated\Object\LabelMonetaryAccount; -use Carbon\Carbon; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Factory\AccountFactory; -use FireflyIII\Models\Account as LocalAccount; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Log; - -/** - * Class PaymentConverter - * @deprecated - * @codeCoverageIgnore - */ -class PaymentConverter -{ - /** @var AccountFactory */ - private $accountFactory; - /** @var AccountRepositoryInterface */ - private $accountRepos; - /** @var array */ - private $configuration; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $importJobRepos; - - public function __construct() - { - $this->accountRepos = app(AccountRepositoryInterface::class); - $this->importJobRepos = app(ImportJobRepositoryInterface::class); - $this->accountFactory = app(AccountFactory::class); - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - /** - * Convert a bunq transaction to a usable transaction for Firefly III. - * - * @param BunqPayment $payment - * - * @param LocalAccount $source - * - * @return array - * @throws FireflyException - */ - public function convert(BunqPayment $payment, LocalAccount $source): array - { - $paymentId = $payment->getId(); - Log::debug(sprintf('Now in convert() for payment with ID #%d', $paymentId)); - Log::debug(sprintf('Source account is assumed to be "%s" (#%d)', $source->name, $source->id)); - $type = TransactionType::WITHDRAWAL; - $counterParty = $payment->getCounterpartyAlias(); - $amount = $payment->getAmount(); - - // some debug info: - Log::debug('Assume its a witdrawal'); - Log::debug(sprintf('Subtype is %s', $payment->getSubType())); - Log::debug(sprintf('Type is %s', $payment->getType())); - Log::debug(sprintf('Amount is %s %s', $amount->getCurrency(), $amount->getValue())); - - $expected = AccountType::EXPENSE; - if (1 === bccomp($amount->getValue(), '0')) { - // amount + means that its a deposit. - $expected = AccountType::REVENUE; - $type = TransactionType::DEPOSIT; - Log::debug(sprintf('Amount is %s %s, so assume this is a deposit.', $amount->getCurrency(), $amount->getValue())); - } - Log::debug(sprintf('Now going to convert counter party to Firefly III account. Expect it to be a "%s" account.', $expected)); - $destination = $this->convertToAccount($counterParty, $expected); - - // switch source and destination if necessary. - if (1 === bccomp($amount->getValue(), '0')) { - Log::debug('Because amount is > 0, will now swap source with destination.'); - [$source, $destination] = [$destination, $source]; - } - - if ($source->accountType->type === AccountType::ASSET && $destination->accountType->type === AccountType::ASSET) { - $type = TransactionType::TRANSFER; - Log::debug('Because both transctions are asset, will make it a transfer.'); - } - Log::debug(sprintf('Bunq created = %s', $payment->getCreated())); - $created = new Carbon($payment->getCreated(), 'UTC'); - // correct timezone to system timezone. - $created->setTimezone(config('app.timezone')); - - $description = $payment->getDescription(); - if ('' === $payment->getDescription() && 'SAVINGS' === $payment->getType()) { - $description = 'Auto-save for savings goal.'; - } - - $storeData = [ - 'user' => $this->importJob->user_id, - 'type' => $type, - 'date' => $created->format('Y-m-d H:i:s'), - 'timestamp' => $created->toAtomString(), - 'description' => $description, - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - 'bill_id' => null, - 'bill_name' => null, - 'tags' => [$payment->getType(), $payment->getSubType()], - 'internal_reference' => $paymentId, - 'external_id' => $paymentId, - 'notes' => null, - 'bunq_payment_id' => $paymentId, - 'original-source' => sprintf('bunq-v%s', config('firefly.version')), - 'transactions' => [ - // single transaction: - [ - 'description' => null, - 'amount' => $amount->getValue(), - 'currency_id' => null, - 'currency_code' => $amount->getCurrency(), - 'foreign_amount' => null, - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - 'budget_id' => null, - 'budget_name' => null, - 'category_id' => null, - 'category_name' => null, - 'source_id' => $source->id, - 'source_name' => null, - 'destination_id' => $destination->id, - 'destination_name' => null, - 'reconciled' => false, - 'identifier' => 0, - ], - ], - ]; - Log::info(sprintf('Parsed %s: "%s" (%s).', $created->format('Y-m-d H:i:s'), $storeData['description'], $storeData['transactions'][0]['amount'])); - - return $storeData; - - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->accountRepos->setUser($importJob->user); - $this->importJobRepos->setUser($importJob->user); - $this->accountFactory->setUser($importJob->user); - $this->configuration = $this->importJobRepos->getConfiguration($importJob); - } - - /** - * @param LabelMonetaryAccount $party - * @param string $expectedType - * - * @return LocalAccount - * @throws FireflyException - */ - private function convertToAccount(LabelMonetaryAccount $party, string $expectedType): LocalAccount - { - Log::debug(sprintf('in convertToAccount() with LabelMonetaryAccount')); - if (null !== $party->getIban()) { - Log::debug(sprintf('Opposing party has IBAN "%s"', $party->getIban())); - - // find account in 'bunq-iban' array first. - $bunqIbans = $this->configuration['bunq-iban'] ?? []; - Log::debug('Bunq ibans configuration is', $bunqIbans); - - if (isset($bunqIbans[$party->getIban()])) { - Log::debug('IBAN is known in array.'); - $accountId = (int)$bunqIbans[$party->getIban()]; - $result = $this->accountRepos->findNull($accountId); - if (null !== $result) { - Log::debug(sprintf('Search for #%s (IBAN "%s"), found "%s" (#%d)', $accountId, $party->getIban(), $result->name, $result->id)); - - return $result; - } - } - - // find opposing party by IBAN second. - $result = $this->accountRepos->findByIbanNull($party->getIban(), [$expectedType]); - if (null !== $result) { - Log::debug(sprintf('Search for "%s" resulted in account "%s" (#%d)', $party->getIban(), $result->name, $result->id)); - - return $result; - } - - // try to find asset account just in case: - if ($expectedType !== AccountType::ASSET) { - $result = $this->accountRepos->findByIbanNull($party->getIban(), [AccountType::ASSET]); - if (null !== $result) { - Log::debug(sprintf('Search for Asset "%s" resulted in account %s (#%d)', $party->getIban(), $result->name, $result->id)); - - return $result; - } - } - } - Log::debug('Found no account for opposing party, must create a new one.'); - - // create new account: - $data = [ - 'user_id' => $this->importJob->user_id, - 'iban' => $party->getIban(), - 'name' => $party->getLabelUser()->getDisplayName(), - 'account_type_id' => null, - 'account_type' => $expectedType, - 'virtual_balance' => null, - 'active' => true, - ]; - $account = $this->accountFactory->create($data); - Log::debug( - sprintf( - 'Converted label monetary account "%s" to NEW "%s" account "%s" (#%d)', - $party->getLabelUser()->getDisplayName(), - $expectedType, - $account->name, $account->id - ) - ); - - return $account; - } - - -} diff --git a/app/Support/Import/Routine/Bunq/StageImportDataHandler.php b/app/Support/Import/Routine/Bunq/StageImportDataHandler.php deleted file mode 100644 index 199d05b7dd..0000000000 --- a/app/Support/Import/Routine/Bunq/StageImportDataHandler.php +++ /dev/null @@ -1,465 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Bunq; - -use bunq\Model\Generated\Endpoint\Payment as BunqPayment; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Factory\AccountFactory; -use FireflyIII\Models\Account as LocalAccount; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\Preference; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Bunq\ApiContext; -use FireflyIII\Services\Bunq\Payment; -use Log; - -/** - * Class StageImportDataHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageImportDataHandler -{ - /** @var int */ - private const DOWNLOAD_BACKWARDS = 1; - /** @var int */ - private const DOWNLOAD_FORWARDS = 2; - - /** @var bool */ - public $stillRunning; - /** @var AccountFactory */ - private $accountFactory; - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var PaymentConverter */ - private $converter; - /** @var ImportJob */ - private $importJob; - /** @var array */ - private $jobConfiguration; - /** @var ImportJobRepositoryInterface */ - private $repository; - /** @var float */ - private $timeStart; - /** @var array */ - private $transactions; - - public function __construct() - { - $this->stillRunning = true; - $this->timeStart = microtime(true); - $this->converter = app(PaymentConverter::class); - - } - - /** - * @codeCoverageIgnore - * @return array - */ - public function getTransactions(): array - { - return $this->transactions; - } - - /** - * @return bool - */ - public function isStillRunning(): bool - { - return $this->stillRunning; - } - - /** - * - * @throws FireflyException - */ - public function run(): void - { - $this->getContext(); - $this->converter->setImportJob($this->importJob); - $config = $this->repository->getConfiguration($this->importJob); - $accounts = $config['accounts'] ?? []; - $mapping = $config['mapping'] ?? []; - $collection = [[]]; - $this->jobConfiguration = $config; - /** @var array $bunqAccount */ - foreach ($accounts as $bunqAccount) { - $bunqAccountId = $bunqAccount['id'] ?? 0; - $localId = $mapping[$bunqAccountId] ?? 0; - if (0 !== $localId && 0 !== $bunqAccountId) { - Log::info(sprintf('Now at bunq account #%d and local account #%d', $bunqAccountId, $localId)); - $localAccount = $this->getLocalAccount((int)$localId); - $collection[] = $this->getTransactionsFromBunq($bunqAccountId, $localAccount); - } - } - $totalSet = array_merge(...$collection); - $this->transactions = $totalSet; - } - - /** - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->transactions = []; - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->accountFactory = app(AccountFactory::class); - $this->repository->setUser($importJob->user); - $this->accountRepository->setUser($importJob->user); - $this->accountFactory->setUser($importJob->user); - } - - /** - * @param BunqPayment $payment - * @param LocalAccount $source - * - * @return array - * @throws FireflyException - */ - private function convertPayment(BunqPayment $payment, LocalAccount $source): array - { - Log::debug(sprintf('Now at payment with ID #%d', $payment->getId())); - - return $this->converter->convert($payment, $source); - } - - /** - * @throws FireflyException - */ - private function getContext(): void - { - /** @var Preference $preference */ - $preference = app('preferences')->getForUser($this->importJob->user, 'bunq_api_context', null); - if (null !== $preference && '' !== (string)$preference->data) { - // restore API context - /** @var ApiContext $apiContext */ - $apiContext = app(ApiContext::class); - $apiContext->fromJson($preference->data); - - return; - } - throw new FireflyException('The bunq API context is unexpectedly empty.'); // @codeCoverageIgnore - } - - /** - * Get the direction in which we must download. - * - * @param int $bunqAccountId - * - * @return int - */ - private function getDirection(int $bunqAccountId): int - { - Log::debug(sprintf('Now in getDirection(%d)', $bunqAccountId)); - - // if oldest transaction ID is 0, AND the newest transaction is 0 - // we don't know about this account, so we must go backward in time. - $oldest = \Preferences::getForUser($this->importJob->user, sprintf('bunq-oldest-transaction-%d', $bunqAccountId), 0); - $newest = \Preferences::getForUser($this->importJob->user, sprintf('bunq-newest-transaction-%d', $bunqAccountId), 0); - - if (0 === $oldest->data && 0 === $newest->data) { - Log::debug(sprintf('Oldest tranaction ID is %d and newest tranasction ID is %d, so go backwards.', $oldest->data, $newest->data)); - - return self::DOWNLOAD_BACKWARDS; - } - - // if newest is not zero but oldest is zero, go forward. - if (0 === $oldest->data && 0 !== $newest->data) { - Log::debug(sprintf('Oldest tranaction ID is %d and newest tranasction ID is %d, so go forwards.', $oldest->data, $newest->data)); - - return self::DOWNLOAD_FORWARDS; - } - - Log::debug(sprintf('Oldest tranaction ID is %d and newest tranasction ID is %d, so go backwards.', $oldest->data, $newest->data)); - - return self::DOWNLOAD_BACKWARDS; - } - - /** - * @param int $accountId - * - * @return LocalAccount - * @throws FireflyException - */ - private function getLocalAccount(int $accountId): LocalAccount - { - $account = $this->accountRepository->findNull($accountId); - if (null === $account) { - throw new FireflyException(sprintf('Cannot find Firefly III asset account with ID #%d. Job must stop now.', $accountId)); // @codeCoverageIgnore - } - if ($account->accountType->type !== AccountType::ASSET) { - throw new FireflyException(sprintf('Account with ID #%d is not an asset account. Job must stop now.', $accountId)); // @codeCoverageIgnore - } - - return $account; - } - - /** - * @param int $bunqAccountId - * @param LocalAccount $localAccount - * - * @return array - * @throws FireflyException - */ - private function getTransactionsFromBunq(int $bunqAccountId, LocalAccount $localAccount): array - { - Log::debug(sprintf('Now in getTransactionsFromBunq(%d).', $bunqAccountId)); - - $direction = $this->getDirection($bunqAccountId); - $return = []; - if (self::DOWNLOAD_BACKWARDS === $direction) { - Log::info('For this account we go backwards in time.'); - // go back either from NULL or from ID. - // ID is the very last transaction downloaded from bunq. - $preference = \Preferences::getForUser($this->importJob->user, sprintf('bunq-oldest-transaction-%d', $bunqAccountId), 0); - $transactionId = 0 === $preference->data ? null : $preference->data; - $return = $this->goBackInTime($bunqAccountId, $localAccount, $transactionId); - } - if (self::DOWNLOAD_FORWARDS === $direction) { - Log::info('For this account we go forwards in time.'); - // go forward from ID. There is no NULL, young padawan - $return = $this->goForwardInTime($bunqAccountId, $localAccount); - } - - return $return; - } - - /** - * This method downloads the transactions from bunq going back in time. Assuming bunq - * is fairly consistent with the transactions it provides through the API, the method - * will store both the highest and the lowest transaction ID downloaded in this manner. - * - * The highest transaction ID is used to continue forward in time. The lowest is used to continue - * even further back in time. - * - * The lowest transaction ID can also be given to this method as a parameter (as $startTransaction). - * - * @param int $bunqAccountId - * @param LocalAccount $localAccount - * @param int $startTransaction - * - * @return array - * @throws FireflyException - */ - private function goBackInTime(int $bunqAccountId, LocalAccount $localAccount, int $startTransaction = null): array - { - Log::debug(sprintf('Now in goBackInTime(#%d, #%s, #%s).', $bunqAccountId, $localAccount->id, $startTransaction)); - $hasMoreTransactions = true; - $olderId = $startTransaction; - $oldestTransaction = null; - $newestTransaction = null; - $count = 0; - $return = []; - - /* - * Do a loop during which we run: - */ - while ($hasMoreTransactions && $this->timeRunning() < 25) { - Log::debug(sprintf('Now in loop #%d', $count)); - Log::debug(sprintf('Now running for %s seconds.', $this->timeRunning())); - - /* - * Send request to bunq. - */ - /** @var Payment $paymentRequest */ - $paymentRequest = app(Payment::class); - $params = ['count' => 197, 'older_id' => $olderId]; - $response = $paymentRequest->listing($bunqAccountId, $params); - $pagination = $response->getPagination(); - Log::debug('Params for the request to bunq are: ', $params); - - /* - * If pagination is not null, we can go back even further. - */ - if (null !== $pagination) { - $olderId = $pagination->getOlderId(); - Log::debug(sprintf('Pagination object is not null, new olderID is "%s"', $olderId)); - } - - /* - * Loop the results from bunq - */ - Log::debug('Now looping results from bunq...'); - /** @var BunqPayment $payment */ - foreach ($response->getValue() as $index => $payment) { - $return[] = $this->convertPayment($payment, $localAccount); - $paymentId = $payment->getId(); - /* - * If oldest and newest transaction are null, they have to be set: - */ - $oldestTransaction = $oldestTransaction ?? $paymentId; - $newestTransaction = $newestTransaction ?? $paymentId; - - /* - * Then, overwrite if appropriate - */ - $oldestTransaction = $paymentId < $oldestTransaction ? $paymentId : $oldestTransaction; - $newestTransaction = $paymentId > $newestTransaction ? $paymentId : $newestTransaction; - } - - /* - * After the loop, check if Firefly III must loop again. - */ - Log::debug(sprintf('Count of result is now %d', count($return))); - $count++; - if (null === $olderId) { - Log::debug('Older ID is NULL, so stop looping cause we are done!'); - $hasMoreTransactions = false; - $this->stillRunning = false; - /* - * We no longer care about the oldest transaction ID: - */ - $oldestTransaction = 0; - } - if (null === $pagination) { - Log::debug('No pagination object, stop looping.'); - $hasMoreTransactions = false; - $this->stillRunning = false; - /* - * We no longer care about the oldest transaction ID: - */ - $oldestTransaction = 0; - } - // sleep 2 seconds to prevent hammering bunq. - sleep(2); - } - // store newest and oldest tranasction ID to be used later: - \Preferences::setForUser($this->importJob->user, sprintf('bunq-oldest-transaction-%d', $bunqAccountId), $oldestTransaction); - \Preferences::setForUser($this->importJob->user, sprintf('bunq-newest-transaction-%d', $bunqAccountId), $newestTransaction); - Log::info(sprintf('Downloaded and parsed %d transactions from bunq.', count($return))); - - return $return; - } - - /** - * @param int $bunqAccountId - * @param LocalAccount $localAccount - * - * @return array - * @throws FireflyException - */ - private function goForwardInTime(int $bunqAccountId, LocalAccount $localAccount): array - { - Log::debug(sprintf('Now in goForwardInTime(%d).', $bunqAccountId)); - $hasMoreTransactions = true; - $count = 0; - $return = []; - $newestTransaction = null; - - /* - * Go forward from the newest transaction we know about: - */ - $preferenceName = sprintf('bunq-newest-transaction-%d', $bunqAccountId); - $transactionPref = \Preferences::getForUser($this->importJob->user, $preferenceName, 0); - $newerId = (int)$transactionPref->data; - - /* - * Run a loop. - */ - while ($hasMoreTransactions && $this->timeRunning() < 25) { - /* - * Debug information: - */ - Log::debug(sprintf('Now in loop #%d', $count)); - Log::debug(sprintf('Now running for %s seconds.', $this->timeRunning())); - - /* - * Send a request to bunq. - */ - /** @var Payment $paymentRequest */ - $paymentRequest = app(Payment::class); - $params = ['count' => 197, 'newer_id' => $newerId]; - $response = $paymentRequest->listing($bunqAccountId, $params); - $pagination = $response->getPagination(); - Log::debug('Submit payment request with params', $params); - - /* - * If pagination is not null, we can go forward even further. - */ - if (null !== $pagination) { - $newerId = $pagination->getNewerId(); - Log::debug(sprintf('Pagination object is not null, newerID is "%s"', $newerId)); - } - Log::debug('Now looping results...'); - /* - * Process the bunq loop. - */ - /** @var BunqPayment $payment */ - foreach ($response->getValue() as $payment) { - $return[] = $this->convertPayment($payment, $localAccount); - $paymentId = $payment->getId(); - - /* - * If oldest and newest transaction are null, they have to be set: - */ - $newestTransaction = $newestTransaction ?? $paymentId; - - /* - * Then, overwrite if appropriate - */ - $newestTransaction = $paymentId > $newestTransaction ? $paymentId : $newestTransaction; - } - - /* - * After the loop, check if Firefly III must loop again. - */ - Log::debug(sprintf('Count of result is now %d', count($return))); - $count++; - if (null === $newerId) { - Log::debug('Newer ID is NULL, so stop looping cause we are done!'); - $hasMoreTransactions = false; - $this->stillRunning = false; - } - if (null === $pagination) { - Log::debug('No pagination object, stop looping.'); - $hasMoreTransactions = false; - $this->stillRunning = false; - } - // sleep 2 seconds to prevent hammering bunq. - sleep(2); - } - - // store newest tranasction ID to be used later: - \Preferences::setForUser($this->importJob->user, sprintf('bunq-newest-transaction-%d', $bunqAccountId), $newestTransaction); - Log::info(sprintf('Downloaded and parsed %d transactions from bunq.', count($return))); - - return $return; - } - - /** - * @return float - */ - private function timeRunning(): float - { - $time_end = microtime(true); - - return $time_end - $this->timeStart; - } -} diff --git a/app/Support/Import/Routine/Bunq/StageNewHandler.php b/app/Support/Import/Routine/Bunq/StageNewHandler.php deleted file mode 100644 index ab844508bc..0000000000 --- a/app/Support/Import/Routine/Bunq/StageNewHandler.php +++ /dev/null @@ -1,379 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Bunq; - -use bunq\exception\BunqException; -use bunq\Model\Generated\Endpoint\MonetaryAccount as BunqMonetaryAccount; -use bunq\Model\Generated\Endpoint\MonetaryAccountBank; -use bunq\Model\Generated\Endpoint\MonetaryAccountJoint; -use bunq\Model\Generated\Endpoint\MonetaryAccountLight; -use bunq\Model\Generated\Endpoint\MonetaryAccountSavings; -use bunq\Model\Generated\Object\CoOwner; -use bunq\Model\Generated\Object\Pointer; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\Preference; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Bunq\ApiContext; -use FireflyIII\Services\Bunq\MonetaryAccount; -use Log; - -/** - * Class StageNewHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageNewHandler -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * @throws FireflyException - */ - public function run(): void - { - Log::info('Now in StageNewHandler::run()'); - /** @var Preference $preference */ - $preference = app('preferences')->getForUser($this->importJob->user, 'bunq_api_context', null); - if (null !== $preference && '' !== (string)$preference->data) { - // restore API context - /** @var ApiContext $apiContext */ - $apiContext = app(ApiContext::class); - $apiContext->fromJson($preference->data); - - // list bunq accounts: - $accounts = $this->listAccounts(); - - // store in job: - $config = $this->repository->getConfiguration($this->importJob); - $config['accounts'] = $accounts; - $this->repository->setConfiguration($this->importJob, $config); - - return; - } - throw new FireflyException('The bunq API context is unexpectedly empty.'); // @codeCoverageIgnore - } // @codeCoverageIgnore - - /** - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - - /** - * @return array - * @throws FireflyException - */ - private function listAccounts(): array - { - Log::debug('Now in StageNewHandler::listAccounts()'); - $accounts = []; - /** @var MonetaryAccount $lister */ - $lister = app(MonetaryAccount::class); - $result = $lister->listing(); - - /** @var BunqMonetaryAccount $monetaryAccount */ - foreach ($result->getValue() as $monetaryAccount) { - try { - $object = $monetaryAccount->getReferencedObject(); - // @codeCoverageIgnoreStart - } catch (BunqException $e) { - throw new FireflyException($e->getMessage()); - } - // @codeCoverageIgnoreEnd - if (null !== $object) { - $array = null; - switch (get_class($object)) { - case MonetaryAccountBank::class: - Log::debug('Going to convert a MonetaryAccountBank'); - /** @var MonetaryAccountBank $object */ - $array = $this->processMab($object); - break; - case MonetaryAccountJoint::class: - Log::debug('Going to convert a MonetaryAccountJoint'); - /** @var MonetaryAccountJoint $object */ - $array = $this->processMaj($object); - break; - case MonetaryAccountLight::class: - Log::debug('Going to convert a MonetaryAccountLight'); - /** @var MonetaryAccountLight $object */ - $array = $this->processMal($object); - break; - case MonetaryAccountSavings::class; - Log::debug('Going to convert a MonetaryAccountSavings'); - /** @var MonetaryAccountSavings $object */ - $array = $this->processMas($object); - break; - default: - // @codeCoverageIgnoreStart - throw new FireflyException(sprintf('Bunq import routine cannot handle account of type "%s".', get_class($object))); - // @codeCoverageIgnoreEnd - } - if (null !== $array) { - Log::debug('Array is not null'); - $accounts[] = $array; - $this->reportFinding($array); - } - } - } - Log::info(sprintf('Found %d account(s) at bunq', count($accounts)), $accounts); - - return $accounts; - } - - /** - * @param MonetaryAccountBank $mab - * - * @return array - */ - private function processMab(MonetaryAccountBank $mab): array - { - $setting = $mab->getSetting(); - $return = [ - 'id' => $mab->getId(), - 'currency_code' => $mab->getCurrency(), - 'description' => $mab->getDescription(), - 'balance' => $mab->getBalance(), - 'status' => $mab->getStatus(), - 'type' => 'MonetaryAccountBank', - 'iban' => null, - 'aliases' => [], - ]; - - if (null !== $setting) { - $return['settings'] = [ - 'color' => $mab->getSetting()->getColor(), - 'default_avatar_status' => $mab->getSetting()->getDefaultAvatarStatus(), - 'restriction_chat' => $mab->getSetting()->getRestrictionChat(), - ]; - } - if (null !== $mab->getAlias()) { - /** @var Pointer $alias */ - foreach ($mab->getAlias() as $alias) { - $return['aliases'][] = [ - 'type' => $alias->getType(), - 'name' => $alias->getName(), - 'value' => $alias->getValue(), - ]; - - // store IBAN alias separately: - if ('IBAN' === $alias->getType()) { - $return['iban'] = $alias->getValue(); - } - } - } - - return $return; - } - - /** - * @param MonetaryAccountJoint $maj - * - * @return array - */ - private function processMaj(MonetaryAccountJoint $maj): array - { - Log::debug('Now processing a MAJ'); - $setting = $maj->getSetting(); - $return = [ - 'id' => $maj->getId(), - 'currency_code' => $maj->getCurrency(), - 'description' => $maj->getDescription(), - 'balance' => $maj->getBalance(), - 'status' => $maj->getStatus(), - 'type' => 'MonetaryAccountJoint', - 'co-owners' => [], - 'aliases' => [], - ]; - - if (null !== $setting) { - $return['settings'] = [ - 'color' => $maj->getSetting()->getColor(), - 'default_avatar_status' => $maj->getSetting()->getDefaultAvatarStatus(), - 'restriction_chat' => $maj->getSetting()->getRestrictionChat(), - ]; - Log::debug('Setting is not null.'); - } - if (null !== $maj->getAlias()) { - Log::debug(sprintf('Alias is not NULL. Count is %d', count($maj->getAlias()))); - /** @var Pointer $alias */ - foreach ($maj->getAlias() as $alias) { - $return['aliases'][] = [ - 'type' => $alias->getType(), - 'name' => $alias->getName(), - 'value' => $alias->getValue(), - ]; - // store IBAN alias separately: - if ('IBAN' === $alias->getType()) { - $return['iban'] = $alias->getValue(); - } - } - } - $coOwners = $maj->getAllCoOwner() ?? []; - Log::debug(sprintf('Count of getAllCoOwner is %d', count($coOwners))); - /** @var CoOwner $coOwner */ - foreach ($coOwners as $coOwner) { - $alias = $coOwner->getAlias(); - if (null !== $alias) { - Log::debug('Alias is not NULL'); - $name = (string)$alias->getDisplayName(); - Log::debug(sprintf('Name is "%s"', $name)); - if ('' !== $name) { - $return['co-owners'][] = $name; - } - } - } - - return $return; - } - - /** - * @param MonetaryAccountLight $mal - * - * @return array - */ - private function processMal(MonetaryAccountLight $mal): array - { - $setting = $mal->getSetting(); - $return = [ - 'id' => $mal->getId(), - 'currency_code' => $mal->getCurrency(), - 'description' => $mal->getDescription(), - 'balance' => $mal->getBalance(), - 'status' => $mal->getStatus(), - 'type' => 'MonetaryAccountLight', - 'aliases' => [], - ]; - - if (null !== $setting) { - $return['settings'] = [ - 'color' => $mal->getSetting()->getColor(), - 'default_avatar_status' => $mal->getSetting()->getDefaultAvatarStatus(), - 'restriction_chat' => $mal->getSetting()->getRestrictionChat(), - ]; - } - if (null !== $mal->getAlias()) { - /** @var Pointer $alias */ - foreach ($mal->getAlias() as $alias) { - $return['aliases'][] = [ - 'type' => $alias->getType(), - 'name' => $alias->getName(), - 'value' => $alias->getValue(), - ]; - // store IBAN alias separately: - if ('IBAN' === $alias->getType()) { - $return['iban'] = $alias->getValue(); - } - } - } - - return $return; - } - - /** - * @param MonetaryAccountSavings $object - * - * @return array - */ - private function processMas(MonetaryAccountSavings $object): array - { - Log::debug('Now in processMas()'); - $setting = $object->getSetting(); - $return = [ - 'id' => $object->getId(), - 'currency_code' => $object->getCurrency(), - 'description' => $object->getDescription(), - 'balance' => $object->getBalance(), - 'status' => $object->getStatus(), - 'type' => 'MonetaryAccountSavings', - 'aliases' => [], - 'savingsGoal' => [], - ]; - - if (null !== $setting) { - $return['settings'] = [ - 'color' => $object->getSetting()->getColor(), - 'default_avatar_status' => $object->getSetting()->getDefaultAvatarStatus(), - 'restriction_chat' => $object->getSetting()->getRestrictionChat(), - ]; - } - if (null !== $object->getAlias()) { - Log::debug('MAS has aliases'); - /** @var Pointer $alias */ - foreach ($object->getAlias() as $alias) { - Log::debug(sprintf('Alias type is "%s", with name "%s" and value "%s"', $alias->getType(), $alias->getName(), $alias->getValue())); - $return['aliases'][] = [ - 'type' => $alias->getType(), - 'name' => $alias->getName(), - 'value' => $alias->getValue(), - ]; - // store IBAN alias separately: - if ('IBAN' === $alias->getType()) { - $return['iban'] = $alias->getValue(); - } - } - } - $goal = $object->getSavingsGoal(); - $return['savingsGoal'] = [ - 'currency' => $goal->getCurrency(), - 'value' => $goal->getValue(), - 'percentage' => $object->getSavingsGoalProgress(), - ]; - Log::debug('End of processMas()', $return); - - return $return; - } - - /** - * Basic report method. - * - * @param array $array - */ - private function reportFinding(array $array): void - { - $bunqId = $array['id'] ?? ''; - $bunqDescription = $array['description'] ?? ''; - $bunqIBAN = ''; - - // find IBAN: - $aliases = $array['aliases'] ?? []; - foreach ($aliases as $alias) { - $type = $alias['type'] ?? 'none'; - if ('IBAN' === $type) { - $bunqIBAN = $alias['value'] ?? ''; - } - } - - Log::info(sprintf('Found account at bunq. ID #%d, title "%s" and IBAN "%s" ', $bunqId, $bunqDescription, $bunqIBAN)); - } -} diff --git a/app/Support/Import/Routine/Fake/StageAhoyHandler.php b/app/Support/Import/Routine/Fake/StageAhoyHandler.php deleted file mode 100644 index a0a81f392b..0000000000 --- a/app/Support/Import/Routine/Fake/StageAhoyHandler.php +++ /dev/null @@ -1,45 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Fake; - -use Log; - -/** - * @codeCoverageIgnore - * Class StageAhoyHandler - * @deprecated - */ -class StageAhoyHandler -{ - /** - */ - public function run(): void - { - for ($i = 0; $i < 5; $i++) { - Log::debug(sprintf('Am now in stage AHOY hander, sleeping... (%d)', $i)); - sleep(1); - } - } - -} diff --git a/app/Support/Import/Routine/Fake/StageFinalHandler.php b/app/Support/Import/Routine/Fake/StageFinalHandler.php deleted file mode 100644 index f3bea38970..0000000000 --- a/app/Support/Import/Routine/Fake/StageFinalHandler.php +++ /dev/null @@ -1,157 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Fake; - -use Carbon\Carbon; -use FireflyIII\Models\ImportJob; - -/** - * @codeCoverageIgnore - * Class StageFinalHandler - * @deprecated - */ -class StageFinalHandler -{ - /** @var ImportJob */ - private $importJob; - - /** - * @return array - * @throws \Exception - */ - public function getTransactions(): array - { - $transactions = []; - - for ($i = 0; $i < 5; $i++) { - $transaction = [ - 'type' => 'withdrawal', - 'date' => Carbon::now()->format('Y-m-d'), - 'tags' => '', - 'user' => $this->importJob->user_id, - - // all custom fields: - 'internal_reference' => null, - 'notes' => null, - - // journal data: - 'description' => 'Some random description #' . random_int(1, 10000), - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - 'bill_id' => null, - 'bill_name' => null, - 'original-source' => sprintf('fake-import-v%s', config('firefly.version')), - - // transaction data: - 'transactions' => [ - [ - 'type' => 'withdrawal', - 'date' => Carbon::now()->format('Y-m-d'), - 'currency_id' => null, - 'currency_code' => 'EUR', - 'description' => 'Some random description #' . random_int(1, 10000), - 'amount' => random_int(500, 5000) / 100, - 'tags' => [], - 'user' => $this->importJob->user_id, - 'budget_id' => null, - 'budget_name' => null, - 'category_id' => null, - 'category_name' => null, - 'source_id' => null, - 'source_name' => 'Checking Account', - 'destination_id' => null, - 'destination_name' => 'Random expense account #' . random_int(1, 10000), - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - 'foreign_amount' => null, - 'reconciled' => false, - 'identifier' => 0, - ], - ], - ]; - - $transactions[] = $transaction; - } - - // add a transfer I know exists already - $transactions[] = [ - 'type' => 'transfer', - 'date' => '2017-02-28', - 'tags' => '', - 'user' => $this->importJob->user_id, - - // all custom fields: - 'internal_reference' => null, - 'notes' => null, - - // journal data: - 'description' => 'Saving money for February', - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - 'bill_id' => null, - 'bill_name' => null, - - // transaction data: - 'transactions' => [ - [ - 'type' => 'transfer', - 'user' => $this->importJob->user_id, - 'date' => '2017-02-28', - 'currency_id' => null, - 'currency_code' => 'EUR', - 'tags' => [], - 'description' => 'Saving money for February', - 'amount' => '140', - 'budget_id' => null, - 'budget_name' => null, - 'category_id' => null, - 'category_name' => null, - 'source_id' => 1, - 'source_name' => 'Checking Account', - 'destination_id' => 2, - 'destination_name' => null, - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - 'foreign_amount' => null, - 'reconciled' => false, - 'identifier' => 0, - ], - ], - ]; - - - return $transactions; - - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - } - -} diff --git a/app/Support/Import/Routine/Fake/StageNewHandler.php b/app/Support/Import/Routine/Fake/StageNewHandler.php deleted file mode 100644 index bf274d8f6e..0000000000 --- a/app/Support/Import/Routine/Fake/StageNewHandler.php +++ /dev/null @@ -1,45 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Fake; - -use Log; - -/** - * @codeCoverageIgnore - * Class StageNewHandler - * @deprecated - */ -class StageNewHandler -{ - /** - */ - public function run(): void - { - for ($i = 0; $i < 5; $i++) { - Log::debug(sprintf('Am now in stage new hander, sleeping... (%d)', $i)); - sleep(1); - } - } - -} diff --git a/app/Support/Import/Routine/File/AssetAccountMapper.php b/app/Support/Import/Routine/File/AssetAccountMapper.php deleted file mode 100644 index b7c4398ae6..0000000000 --- a/app/Support/Import/Routine/File/AssetAccountMapper.php +++ /dev/null @@ -1,135 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\User; -use Log; - -/** - * Class AssetAccountMapper - * Can also handle liability accounts. - * @deprecated - */ -class AssetAccountMapper -{ - /** @var int */ - private $defaultAccount; - /** @var AccountRepositoryInterface */ - private $repository; - /** @var User */ - private $user; - - /** @var array */ - private $types; - - /** - * AssetAccountMapper constructor. - */ - public function __construct() - { - $this->types = [AccountType::ASSET, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]; - } - - /** - * Based upon data in the importable, try to find or create the asset account account. - * - * @param int|null $accountId - * @param array $data - * - * @return Account - * - */ - public function map(?int $accountId, array $data): Account - { - Log::debug(sprintf('Now in AssetAccountMapper::map(%d)', $accountId), $data); - if ((int)$accountId > 0) { - // find asset account with this ID: - $result = $this->repository->findNull($accountId); - if (null !== $result && in_array($result->accountType->type, $this->types, true)) { - Log::debug(sprintf('Found %s "%s" based on given ID %d', $result->accountType->type, $result->name, $accountId)); - - return $result; - } - if (null !== $result && in_array($result->accountType->type, $this->types, true)) { - Log::warning( - sprintf('Found account "%s" based on given ID %d but its a %s, return nothing.', $result->name, $accountId, $result->accountType->type) - ); - } - } - // find by (respectively): - // IBAN, accountNumber, name, - $fields = ['iban' => 'findByIbanNull', 'number' => 'findByAccountNumber', 'name' => 'findByName']; - foreach ($fields as $field => $function) { - $value = (string)($data[$field] ?? ''); - if ('' === $value) { - Log::debug(sprintf('Array does not contain a value for %s. Continue', $field)); - continue; - } - $result = $this->repository->$function($value, $this->types); - Log::debug(sprintf('Going to run %s() with argument "%s" (asset account or liability)', $function, $value)); - if (null !== $result) { - Log::debug(sprintf('Found asset account "%s". Return it!', $result->name)); - - return $result; - } - } - Log::debug('Found nothing. Will return default account.'); - // still NULL? Return default account. - $default = null; - if ($this->defaultAccount > 0) { - $default = $this->repository->findNull($this->defaultAccount); - } - if (null === $default) { - Log::debug('Default account is NULL! Simply result first account in system.'); - $default = $this->repository->getAccountsByType([AccountType::ASSET])->first(); - } - - Log::debug(sprintf('Return default account "%s" (#%d). Return it!', $default->name, $default->id)); - - return $default; - } - - /** - * @param int $defaultAccount - */ - public function setDefaultAccount(int $defaultAccount): void - { - $this->defaultAccount = $defaultAccount; - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - $this->repository = app(AccountRepositoryInterface::class); - $this->defaultAccount = 0; - $this->repository->setUser($user); - - } -} diff --git a/app/Support/Import/Routine/File/CSVProcessor.php b/app/Support/Import/Routine/File/CSVProcessor.php deleted file mode 100644 index 225d16d0d6..0000000000 --- a/app/Support/Import/Routine/File/CSVProcessor.php +++ /dev/null @@ -1,91 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use Log; - - -/** - * Class CSVProcessor - * @deprecated - * @codeCoverageIgnore - */ -class CSVProcessor implements FileProcessorInterface -{ - /** @var ImportJob */ - private $importJob; - - /** - * Fires the file processor. - * - * @return array - * @throws FireflyException - */ - public function run(): array - { - Log::debug('Now in CSVProcessor() run'); - - // create separate objects to handle separate tasks: - /** @var LineReader $lineReader */ - $lineReader = app(LineReader::class); - $lineReader->setImportJob($this->importJob); - $lines = $lineReader->getLines(); - - // convert each line into a small set of "ColumnValue" objects, - // joining each with its mapped counterpart. - /** @var MappingConverger $mappingConverger */ - $mappingConverger = app(MappingConverger::class); - $mappingConverger->setImportJob($this->importJob); - $converged = $mappingConverger->converge($lines); - - // validate mapped values: - /** @var MappedValuesValidator $validator */ - $validator = app(MappedValuesValidator::class); - $validator->setImportJob($this->importJob); - $mappedValues = $validator->validate($mappingConverger->getMappedValues()); - - // make import transaction things from these objects. - /** @var ImportableCreator $creator */ - $creator = app(ImportableCreator::class); - $importables = $creator->convertSets($converged); - - /** @var ImportableConverter $converter */ - $converter = app(ImportableConverter::class); - $converter->setImportJob($this->importJob); - $converter->setMappedValues($mappedValues); - - return $converter->convert($importables); - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - Log::debug('Now in setImportJob()'); - $this->importJob = $importJob; - } -} diff --git a/app/Support/Import/Routine/File/CurrencyMapper.php b/app/Support/Import/Routine/File/CurrencyMapper.php deleted file mode 100644 index 89d8aebe90..0000000000 --- a/app/Support/Import/Routine/File/CurrencyMapper.php +++ /dev/null @@ -1,103 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\User; -use Log; - -/** - * Class CurrencyMapper - * @deprecated - * @codeCoverageIgnore - */ -class CurrencyMapper -{ - /** @var CurrencyRepositoryInterface */ - private $repository; - /** @var User */ - private $user; - - /** - * @param int|null $currencyId - * @param array $data - * - * @return TransactionCurrency|null - */ - public function map(?int $currencyId, array $data): ?TransactionCurrency - { - Log::debug('Now in CurrencyMapper::map()'); - if ((int)$currencyId > 0) { - $result = $this->repository->findNull($currencyId); - if (null !== $result) { - Log::debug(sprintf('Found currency %s based on ID, return it.', $result->code)); - - return $result; - } - } - // try to find it by all other fields. - $fields = ['code' => 'findByCodeNull', 'symbol' => 'findBySymbolNull', 'name' => 'findByNameNull']; - foreach ($fields as $field => $function) { - $value = (string)($data[$field] ?? ''); - if ('' === $value) { - Log::debug(sprintf('Array does not contain a value for %s. Continue', $field)); - continue; - } - Log::debug(sprintf('Will search for currency using %s() and argument "%s".', $function, $value)); - $result = $this->repository->$function($value); - if (null !== $result) { - Log::debug(sprintf('Found result: Currency #%d, code "%s"', $result->id, $result->code)); - - return $result; - } - } - if (!isset($data['code'])) { - return null; - } - - // if still nothing, and fields not null, try to create it - $creation = [ - 'code' => $data['code'], - 'name' => $data['name'] ?? $data['code'], - 'symbol' => $data['symbol'] ?? $data['code'], - 'enabled' => true, - 'decimal_places' => 2, - ]; - - // could be NULL - return $this->repository->store($creation); - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - $this->repository = app(CurrencyRepositoryInterface::class); - $this->repository->setUser($user); - } - -} diff --git a/app/Support/Import/Routine/File/FileProcessorInterface.php b/app/Support/Import/Routine/File/FileProcessorInterface.php deleted file mode 100644 index 5835f5ec9a..0000000000 --- a/app/Support/Import/Routine/File/FileProcessorInterface.php +++ /dev/null @@ -1,50 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Models\ImportJob; - - -/** - * Interface FileProcessorInterface - * @deprecated - * @codeCoverageIgnore - */ -interface FileProcessorInterface -{ - - /** - * Fires the file processor. - * - * @return array - */ - public function run(): array; - - /** - * Set values. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void; -} diff --git a/app/Support/Import/Routine/File/ImportableConverter.php b/app/Support/Import/Routine/File/ImportableConverter.php deleted file mode 100644 index b512a66122..0000000000 --- a/app/Support/Import/Routine/File/ImportableConverter.php +++ /dev/null @@ -1,347 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use Carbon\Carbon; -use Carbon\Exceptions\InvalidDateException; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Placeholder\ImportTransaction; -use InvalidArgumentException; -use Log; - -/** - * Class ImportableConverter - * @deprecated - * @codeCoverageIgnore - */ -class ImportableConverter -{ - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var AssetAccountMapper */ - private $assetMapper; - /** @var array */ - private $config; - /** @var CurrencyMapper */ - private $currencyMapper; - /** @var TransactionCurrency */ - private $defaultCurrency; - /** @var ImportJob */ - private $importJob; - /** @var array */ - private $mappedValues; - /** @var OpposingAccountMapper */ - private $opposingMapper; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Convert ImportTransaction to factory-compatible array. - * - * @param array $importables - * - * @return array - */ - public function convert(array $importables): array - { - $total = count($importables); - Log::debug(sprintf('Going to convert %d import transactions', $total)); - $result = []; - /** @var ImportTransaction $importable */ - foreach ($importables as $index => $importable) { - Log::debug(sprintf('Now going to parse importable %d of %d', $index + 1, $total)); - try { - $entry = $this->convertSingle($importable); - } catch (FireflyException $e) { - $this->repository->addErrorMessage($this->importJob, sprintf('Row #%d: %s', $index + 1, $e->getMessage())); - continue; - } - if (null !== $entry) { - $result[] = $entry; - Log::debug('Final result of importable converter', $entry); - } - } - - return $result; - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->config = $importJob->configuration; - - // repository is used for error messages - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - - // asset account mapper can map asset accounts (makes sense right?) - $this->assetMapper = app(AssetAccountMapper::class); - $this->assetMapper->setUser($importJob->user); - $this->assetMapper->setDefaultAccount($this->config['import-account'] ?? 0); - - // asset account repository is used for currency information - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->accountRepository->setUser($importJob->user); - - // opposing account mapper: - $this->opposingMapper = app(OpposingAccountMapper::class); - $this->opposingMapper->setUser($importJob->user); - - // currency mapper: - $this->currencyMapper = app(CurrencyMapper::class); - $this->currencyMapper->setUser($importJob->user); - $this->defaultCurrency = app('amount')->getDefaultCurrencyByUser($importJob->user); - } - - /** - * @codeCoverageIgnore - * - * @param array $mappedValues - */ - public function setMappedValues(array $mappedValues): void - { - $this->mappedValues = $mappedValues; - } - - /** - * @param string|null $date - * - * @return string|null - */ - private function convertDateValue(string $date = null): ?string - { - $result = null; - if (null !== $date) { - try { - // add exclamation mark for better parsing. http://php.net/manual/en/datetime.createfromformat.php - $dateFormat = $this->config['date-format'] ?? 'Ymd'; - if ('!' !== $dateFormat[0]) { - $dateFormat = '!' . $dateFormat; - } - $object = Carbon::createFromFormat($dateFormat, $date); - $result = $object->format('Y-m-d H:i:s'); - Log::debug(sprintf('createFromFormat: Turning "%s" into "%s" using "%s"', $date, $result, $this->config['date-format'] ?? 'Ymd')); - } catch (InvalidDateException|InvalidArgumentException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - } - } - - return $result; - } - - /** - * @param ImportTransaction $importable - * - * @return array - * @throws FireflyException - */ - private function convertSingle(ImportTransaction $importable): array - { - Log::debug(sprintf('Description is: "%s"', $importable->description)); - $foreignAmount = $importable->calculateForeignAmount(); - $amount = $importable->calculateAmount(); - - Log::debug('All meta data: ', $importable->meta); - - if ('' === $amount) { - $amount = $foreignAmount; - } - if ('' === $amount) { - throw new FireflyException('No transaction amount information.'); - } - - // amount is 0? skip - if (0 === bccomp($amount, '0')) { - throw new FireflyException('Amount of transaction is zero.'); - } - - $source = $this->assetMapper->map($importable->accountId, $importable->getAccountData()); - $destination = $this->opposingMapper->map($importable->opposingId, $amount, $importable->getOpposingAccountData()); - - // if the amount is positive, switch source and destination (account and opposing account) - if (1 === bccomp($amount, '0')) { - $source = $this->opposingMapper->map($importable->opposingId, $amount, $importable->getOpposingAccountData()); - $destination = $this->assetMapper->map($importable->accountId, $importable->getAccountData()); - Log::debug( - sprintf( - '%s is positive, so "%s" (#%d) is now source and "%s" (#%d) is now destination.', - $amount, $source->name, $source->id, $destination->name, $destination->id - ) - ); - } - - $currency = $this->currencyMapper->map($importable->currencyId, $importable->getCurrencyData()); - $foreignCurrency = $this->currencyMapper->map($importable->foreignCurrencyId, $importable->getForeignCurrencyData()); - - Log::debug(sprintf('"%s" (#%d) is source and "%s" (#%d) is destination.', $source->name, $source->id, $destination->name, $destination->id)); - - - if ($destination->id === $source->id) { - throw new FireflyException( - sprintf( - 'Source ("%s", #%d) and destination ("%s", #%d) are the same account.', $source->name, $source->id, $destination->name, $destination->id - ) - ); - } - - $transactionType = $this->getTransactionType($source->accountType->type, $destination->accountType->type); - $currency = $currency ?? $this->getCurrency($source, $destination); - - if ('unknown' === $transactionType) { - $message = sprintf( - 'Cannot determine transaction type. Source account is a %s, destination is a %s', $source->accountType->type, $destination->accountType->type - ); - Log::error($message, ['source' => $source->toArray(), 'dest' => $destination->toArray()]); - throw new FireflyException($message); - } - - return [ - - 'user' => $this->importJob->user_id, - 'group_title' => null, - 'transactions' => [ - [ - 'user' => $this->importJob->user_id, - 'type' => strtolower($transactionType), - 'date' => $this->convertDateValue($importable->date) ?? Carbon::now()->format('Y-m-d H:i:s'), - 'order' => 0, - - 'currency_id' => $currency->id, - 'currency_code' => null, - - 'foreign_currency_id' => $importable->foreignCurrencyId, - 'foreign_currency_code' => null === $foreignCurrency ? null : $foreignCurrency->code, - - 'amount' => $amount, - 'foreign_amount' => $foreignAmount, - - 'description' => $importable->description, - - 'source_id' => $source->id, - 'source_name' => null, - 'destination_id' => $destination->id, - 'destination_name' => null, - - 'budget_id' => $importable->budgetId, - 'budget_name' => $importable->budgetName, - - 'category_id' => $importable->categoryId, - 'category_name' => $importable->categoryName, - - 'bill_id' => $importable->billId, - 'bill_name' => $importable->billName, - - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - - 'reconciled' => false, - - 'notes' => $importable->note, - 'tags' => $importable->tags, - - 'internal_reference' => $importable->meta['internal_reference'] ?? null, - 'external_id' => $importable->externalId, - 'original_source' => $importable->meta['original_source'] ?? null, - - 'sepa_cc' => $importable->meta['sepa_cc'] ?? null, - 'sepa_ct_op' => $importable->meta['sepa_ct_op'] ?? null, - 'sepa_ct_id' => $importable->meta['sepa_ct_id'] ?? null, - 'sepa_db' => $importable->meta['sepa_db'] ?? null, - 'sepa_country' => $importable->meta['sepa_country'] ?? null, - 'sepa_ep' => $importable->meta['sepa_ep'] ?? null, - 'sepa_ci' => $importable->meta['sepa_ci'] ?? null, - 'sepa_batch_id' => $importable->meta['sepa_batch_id'] ?? null, - - 'interest_date' => $this->convertDateValue($importable->meta['date_interest'] ?? null), - 'book_date' => $this->convertDateValue($importable->meta['date_book'] ?? null), - 'process_date' => $this->convertDateValue($importable->meta['date_process'] ?? null), - 'due_date' => $this->convertDateValue($importable->meta['date_due'] ?? null), - 'payment_date' => $this->convertDateValue($importable->meta['date_payment'] ?? null), - 'invoice_date' => $this->convertDateValue($importable->meta['date_invoice'] ?? null), - ], - ], - ]; - - } - - /** - * @param Account $source - * @param Account $destination - * - * @return TransactionCurrency - */ - private function getCurrency(Account $source, Account $destination): TransactionCurrency - { - $currency = null; - if ($destination->accountType->type === AccountType::ASSET) { - // destination is asset, might have currency preference: - $destinationCurrencyId = (int)$this->accountRepository->getMetaValue($destination, 'currency_id'); - $currency = 0 === $destinationCurrencyId ? $this->defaultCurrency : $this->currencyMapper->map($destinationCurrencyId, []); - Log::debug(sprintf('Destination is an asset account, and has currency preference %s', $currency->code)); - } - - if ($source->accountType->type === AccountType::ASSET) { - // source is asset, might have currency preference: - $sourceCurrencyId = (int)$this->accountRepository->getMetaValue($source, 'currency_id'); - $currency = 0 === $sourceCurrencyId ? $this->defaultCurrency : $this->currencyMapper->map($sourceCurrencyId, []); - Log::debug(sprintf('Source is an asset account, and has currency preference %s', $currency->code)); - } - if (null === $currency) { - Log::debug(sprintf('Could not map currency, use default (%s)', $this->defaultCurrency->code)); - $currency = $this->defaultCurrency; - } - - return $currency; - } - - /** - * @param string $source - * @param string $destination - * - * @return string - */ - private function getTransactionType(string $source, string $destination): string - { - $type = 'unknown'; - - $newType = config(sprintf('firefly.account_to_transaction.%s.%s', $source, $destination)); - if (null !== $newType) { - Log::debug(sprintf('Source is %s, destination is %s, so this is a %s.', $source, $destination, $newType)); - - return (string)$newType; - } - - return $type; - } -} diff --git a/app/Support/Import/Routine/File/ImportableCreator.php b/app/Support/Import/Routine/File/ImportableCreator.php deleted file mode 100644 index e86230a6c4..0000000000 --- a/app/Support/Import/Routine/File/ImportableCreator.php +++ /dev/null @@ -1,73 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Support\Import\Placeholder\ColumnValue; -use FireflyIII\Support\Import\Placeholder\ImportTransaction; - -/** - * Takes an array of arrays of ColumnValue objects and returns one (1) ImportTransaction - * for each line. - * - * @deprecated - * @codeCoverageIgnore - * - * Class ImportableCreator - */ -class ImportableCreator -{ - /** - * @param array $sets - * - * @return array - * @throws \FireflyIII\Exceptions\FireflyException - */ - public function convertSets(array $sets): array - { - $return = []; - foreach ($sets as $set) { - $return[] = $this->convertSet($set); - } - - return $return; - } - - /** - * @param array $set - * - * @return ImportTransaction - * @throws \FireflyIII\Exceptions\FireflyException - */ - private function convertSet(array $set): ImportTransaction - { - $transaction = new ImportTransaction; - /** @var ColumnValue $entry */ - foreach ($set as $entry) { - $transaction->addColumnValue($entry); - } - - return $transaction; - } - -} diff --git a/app/Support/Import/Routine/File/LineReader.php b/app/Support/Import/Routine/File/LineReader.php deleted file mode 100644 index b859dfcacb..0000000000 --- a/app/Support/Import/Routine/File/LineReader.php +++ /dev/null @@ -1,189 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use Exception; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; -use FireflyIII\Import\Specifics\SpecificInterface; -use FireflyIII\Models\Attachment; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use League\Csv\Reader; -use League\Csv\Statement; -use Log; - -/** - * Class LineReader - * @deprecated - * @codeCoverageIgnore - */ -class LineReader -{ - /** @var AttachmentHelperInterface */ - private $attachments; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Grab all lines from the import job. - * - * @return array - * @throws FireflyException - */ - public function getLines(): array - { - try { - $reader = $this->getReader(); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - Log::error($e->getMessage()); - throw new FireflyException('Cannot get reader: ' . $e->getMessage()); - } - // @codeCoverageIgnoreEnd - // get all lines from file: - $lines = $this->getAllLines($reader); - - // apply specifics and return. - return $this->applySpecifics($lines); - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->attachments = app(AttachmentHelperInterface::class); - $this->repository->setUser($importJob->user); - } - - /** - * @param array $lines - * - * @return array - */ - private function applySpecifics(array $lines): array - { - $config = $this->importJob->configuration; - $validSpecifics = array_keys(config('csv.import_specifics')); - $specifics = $config['specifics'] ?? []; - $names = array_keys($specifics); - $toApply = []; - foreach ($names as $name) { - if (!in_array($name, $validSpecifics, true)) { - continue; - } - $class = config(sprintf('csv.import_specifics.%s', $name)); - $toApply[] = app($class); - } - $return = []; - /** @var array $line */ - foreach ($lines as $line) { - /** @var SpecificInterface $specific */ - foreach ($toApply as $specific) { - $line = $specific->run($line); - } - $return[] = $line; - } - - return $return; - } - - /** - * @param Reader $reader - * - * @return array - * @throws FireflyException - */ - private function getAllLines(Reader $reader): array - { - /** @var array $config */ - $config = $this->importJob->configuration; - Log::debug('now in getLines()'); - $offset = isset($config['has-headers']) && true === $config['has-headers'] ? 1 : 0; - try { - $stmt = (new Statement)->offset($offset); - // @codeCoverageIgnoreStart - } catch (Exception $e) { - throw new FireflyException(sprintf('Could not execute statement: %s', $e->getMessage())); - } - // @codeCoverageIgnoreEnd - $results = $stmt->process($reader); - $lines = []; - foreach ($results as $line) { - - $lineValues = array_values($line); - - // do a first sanity check on whatever comes out of the CSV file. - array_walk( - $lineValues, static function ($element) { - $element = str_replace(' ', ' ', (string)$element); - - return $element; - } - ); - - $lines[] = $lineValues; - } - - - return $lines; - } - - /** - * @return Reader - * @throws FireflyException - */ - private function getReader(): Reader - { - Log::debug('Now in getReader()'); - $content = ''; - $collection = $this->repository->getAttachments($this->importJob); - /** @var Attachment $attachment */ - foreach ($collection as $attachment) { - if ('import_file' === $attachment->filename) { - $content = $this->attachments->getAttachmentContent($attachment); - break; - } - } - $config = $this->repository->getConfiguration($this->importJob); - $reader = Reader::createFromString($content); - try { - $reader->setDelimiter($config['delimiter'] ?? ','); - // @codeCoverageIgnoreStart - } catch (\League\Csv\Exception $e) { - throw new FireflyException(sprintf('Cannot set delimiter: %s', $e->getMessage())); - } - - // @codeCoverageIgnoreEnd - - return $reader; - } - - -} diff --git a/app/Support/Import/Routine/File/MappedValuesValidator.php b/app/Support/Import/Routine/File/MappedValuesValidator.php deleted file mode 100644 index a3a23dc12d..0000000000 --- a/app/Support/Import/Routine/File/MappedValuesValidator.php +++ /dev/null @@ -1,134 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\Bill\BillRepositoryInterface; -use FireflyIII\Repositories\Budget\BudgetRepositoryInterface; -use FireflyIII\Repositories\Category\CategoryRepositoryInterface; -use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Log; - -/** - * Class MappedValuesValidator - * @deprecated - * @codeCoverageIgnore - */ -class MappedValuesValidator -{ - /** @var AccountRepositoryInterface */ - private $accountRepos; - /** @var BillRepositoryInterface */ - private $billRepos; - /** @var BudgetRepositoryInterface */ - private $budgetRepos; - /** @var CategoryRepositoryInterface */ - private $catRepos; - /** @var CurrencyRepositoryInterface */ - private $currencyRepos; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepos = app(AccountRepositoryInterface::class); - $this->currencyRepos = app(CurrencyRepositoryInterface::class); - $this->billRepos = app(BillRepositoryInterface::class); - $this->budgetRepos = app(BudgetRepositoryInterface::class); - $this->catRepos = app(CategoryRepositoryInterface::class); - - $this->repository->setUser($importJob->user); - $this->accountRepos->setUser($importJob->user); - $this->currencyRepos->setUser($importJob->user); - $this->billRepos->setUser($importJob->user); - $this->budgetRepos->setUser($importJob->user); - $this->catRepos->setUser($importJob->user); - } - - - /** - * @param array $mappings - * - * @return array - * @throws FireflyException - * - */ - public function validate(array $mappings): array - { - $return = []; - Log::debug('Now in validateMappedValues()'); - foreach ($mappings as $role => $values) { - Log::debug(sprintf('Now at role "%s"', $role)); - $values = array_unique($values); - if (count($values) > 0) { - switch ($role) { - default: - throw new FireflyException(sprintf('Cannot validate mapped values for role "%s"', $role)); // @codeCoverageIgnore - case 'opposing-id': - case 'account-id': - $set = $this->accountRepos->getAccountsById($values); - $valid = $set->pluck('id')->toArray(); - $return[$role] = $valid; - break; - case 'currency-id': - case 'foreign-currency-id': - $set = $this->currencyRepos->getByIds($values); - $valid = $set->pluck('id')->toArray(); - $return[$role] = $valid; - break; - case 'bill-id': - $set = $this->billRepos->getByIds($values); - $valid = $set->pluck('id')->toArray(); - $return[$role] = $valid; - break; - case 'budget-id': - $set = $this->budgetRepos->getByIds($values); - $valid = $set->pluck('id')->toArray(); - $return[$role] = $valid; - break; - case 'category-id': - Log::debug('Going to validate these category ids: ', $values); - $set = $this->catRepos->getByIds($values); - $valid = $set->pluck('id')->toArray(); - $return[$role] = $valid; - Log::debug('Valid category IDs are: ', $valid); - break; - } - } - } - - return $return; - } -} diff --git a/app/Support/Import/Routine/File/MappingConverger.php b/app/Support/Import/Routine/File/MappingConverger.php deleted file mode 100644 index 3a127ed8e2..0000000000 --- a/app/Support/Import/Routine/File/MappingConverger.php +++ /dev/null @@ -1,216 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\Import\Placeholder\ColumnValue; -use Log; - -/** - * Class MappingConverger - * @deprecated - * @codeCoverageIgnore - */ -class MappingConverger -{ - /** @var array */ - private $doMapping; - /** @var ImportJob */ - private $importJob; - /** @var array */ - private $mappedValues; - /** @var array */ - private $mapping; - /** @var ImportJobRepositoryInterface */ - private $repository; - /** @var array */ - private $roles; - - /** - * Each cell in the CSV file could be linked to a mapped value. This depends on the role of - * the column and the content of the cell. This method goes over all cells, and using their - * associated role, will see if it has been linked to a mapped value. These mapped values - * are all IDs of objects in the Firefly III database. - * - * If such a mapping exists the role of the cell changes to whatever the mapped value is. - * - * Examples: - * - * - Cell with content "Checking Account" and role "account-name". Mapping links "Checking Account" to account-id 2. - * - Cell with content "Checking Account" and role "description". No mapping, so value and role remains the same. - * - * @param array $lines - * - * @return array - * @throws FireflyException - */ - public function converge(array $lines): array - { - Log::debug('Start converging process.'); - $collection = []; - $total = count($lines); - /** @var array $line */ - foreach ($lines as $lineIndex => $line) { - Log::debug(sprintf('Now converging line %d out of %d.', $lineIndex + 1, $total)); - $set = $this->processLine($line); - $collection[] = $set; - } - - return $collection; - - } - - /** - * @codeCoverageIgnore - * @return array - */ - public function getMappedValues(): array - { - return $this->mappedValues; - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - $this->mappedValues = []; - $config = $importJob->configuration; - $this->roles = $config['column-roles'] ?? []; - $this->mapping = $config['column-mapping-config'] ?? []; - $this->doMapping = $config['column-do-mapping'] ?? []; - } - - /** - * If the value in the column is mapped to a certain ID, - * the column where this ID must be placed will change. - * - * For example, if you map role "budget-name" with value "groceries" to 1, - * then that should become the budget-id. Not the name. - * - * @param int $column - * @param int $mapped - * - * @return string - * @throws FireflyException - */ - private function getRoleForColumn(int $column, int $mapped): string - { - $role = $this->roles[$column] ?? '_ignore'; - if (0 === $mapped) { - Log::debug(sprintf('Column #%d with role "%s" is not mapped.', $column, $role)); - - return $role; - } - if (!(isset($this->doMapping[$column]) && true === $this->doMapping[$column])) { - - // if the mapping has been filled in already by a role with a higher priority, - // ignore the mapping. - Log::debug(sprintf('Column #%d ("%s") has something.', $column, $role)); - - - return $role; - } - $roleMapping = [ - 'account-id' => 'account-id', - 'account-name' => 'account-id', - 'account-iban' => 'account-id', - 'account-number' => 'account-id', - 'bill-id' => 'bill-id', - 'bill-name' => 'bill-id', - 'budget-id' => 'budget-id', - 'budget-name' => 'budget-id', - 'currency-id' => 'currency-id', - 'currency-name' => 'currency-id', - 'currency-code' => 'currency-id', - 'currency-symbol' => 'currency-id', - 'category-id' => 'category-id', - 'category-name' => 'category-id', - 'foreign-currency-id' => 'foreign-currency-id', - 'foreign-currency-code' => 'foreign-currency-id', - 'opposing-id' => 'opposing-id', - 'opposing-name' => 'opposing-id', - 'opposing-iban' => 'opposing-id', - 'opposing-number' => 'opposing-id', - ]; - if (!isset($roleMapping[$role])) { - throw new FireflyException(sprintf('Cannot indicate new role for mapped role "%s"', $role)); // @codeCoverageIgnore - } - $newRole = $roleMapping[$role]; - Log::debug(sprintf('Role was "%s", but because of mapping (mapped to #%d), role becomes "%s"', $role, $mapped, $newRole)); - - // also store the $mapped values in a "mappedValues" array. - $this->mappedValues[$newRole][] = $mapped; - Log::debug(sprintf('Values mapped to role "%s" are: ', $newRole), $this->mappedValues[$newRole]); - - return $newRole; - } - - /** - * @param array $line - * - * @return array - * @throws FireflyException - */ - private function processLine(array $line): array - { - $return = []; - foreach ($line as $columnIndex => $value) { - $value = trim($value); - $originalRole = $this->roles[$columnIndex] ?? '_ignore'; - Log::debug(sprintf('Now at column #%d (%s), value "%s"', $columnIndex, $originalRole, $value)); - if ('_ignore' !== $originalRole && '' != $value) { - - // is a mapped value present? - $mapped = $this->mapping[$columnIndex][$value] ?? 0; - // the role might change. - $role = $this->getRoleForColumn($columnIndex, $mapped); - - $columnValue = new ColumnValue; - $columnValue->setValue($value); - $columnValue->setRole($role); - $columnValue->setMappedValue($mapped); - $columnValue->setOriginalRole($originalRole); - $return[] = $columnValue; - } - if ('' === $value) { - Log::debug('Column skipped because value is empty.'); - } - } - // add a special column value for the "source" - $columnValue = new ColumnValue; - $columnValue->setValue(sprintf('csv-import-v%s', config('firefly.version'))); - $columnValue->setMappedValue(0); - $columnValue->setRole('original-source'); - $return[] = $columnValue; - - return $return; - } - -} diff --git a/app/Support/Import/Routine/File/OFXProcessor.php b/app/Support/Import/Routine/File/OFXProcessor.php deleted file mode 100644 index 0cb893f26a..0000000000 --- a/app/Support/Import/Routine/File/OFXProcessor.php +++ /dev/null @@ -1,121 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - - -use FireflyIII\Helpers\Attachments\AttachmentHelperInterface; -use FireflyIII\Models\Attachment; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use Log; -use OfxParser\Entities\BankAccount; -use OfxParser\Entities\Transaction; - -/** - * - * Class OFXProcessor - * @deprecated - * @codeCoverageIgnore - */ -class OFXProcessor implements FileProcessorInterface -{ - /** @var AttachmentHelperInterface */ - private $attachments; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Fires the file processor. - * - * @return array - */ - public function run(): array - { - $collection = $this->repository->getAttachments($this->importJob); - $content = ''; - /** @var Attachment $attachment */ - foreach ($collection as $attachment) { - if ('import_file' === $attachment->filename) { - $content = $this->attachments->getAttachmentContent($attachment); - break; - } - } - $config = $this->repository->getConfiguration($this->importJob); - try { - Log::debug('Now in OFXProcessor() run'); - $ofxParser = new \OfxParser\Parser(); - $ofx = $ofxParser->loadFromString($content); - } catch (\Exception $e) { - echo $e->getMessage(); - exit; - } - reset($ofx->bankAccounts); - /** @var BankAccount $bankAccount */ - foreach ($ofx->bankAccounts as $bankAccount) { - /** @var Transaction $transaction */ - foreach ($bankAccount->statement->transactions as $transaction) { - //var_dump($transaction); - } - } - - // - // // Get the statement start and end dates - // $startDate = $bankAccount->statement->startDate; - // $endDate = $bankAccount->statement->endDate; - // var_dump($startDate); - // var_dump($endDate); - // - // // Get the statement transactions for the account - // $transactions = $bankAccount->statement->transactions; - // foreach($transactions as $transaction) { - // var_dump($transaction); - // } - // - // die('I am here.'); - - - exit; - - - return []; - } - - /** - * Set values. - * - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - Log::debug('Now in setImportJob()'); - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->attachments = app(AttachmentHelperInterface::class); - - $this->repository->setUser($importJob->user); - - } -} diff --git a/app/Support/Import/Routine/File/OpposingAccountMapper.php b/app/Support/Import/Routine/File/OpposingAccountMapper.php deleted file mode 100644 index 342a121e9e..0000000000 --- a/app/Support/Import/Routine/File/OpposingAccountMapper.php +++ /dev/null @@ -1,144 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\File; - -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\User; -use Log; - -/** - * Class OpposingAccountMapper - * @deprecated - * @codeCoverageIgnore - */ -class OpposingAccountMapper -{ - /** @var AccountRepositoryInterface */ - private $repository; - /** @var User */ - private $user; - - /** - * @param int|null $accountId - * @param string $amount - * @param array $data - * - * @return Account - * - */ - public function map(?int $accountId, string $amount, array $data): Account - { - Log::debug(sprintf('Now in OpposingAccountMapper::map(%d, "%s")', $accountId, $amount), $data); - // default assumption is we're looking for an expense account. - $expectedType = AccountType::EXPENSE; - $result = null; - Log::debug(sprintf('Going to search for accounts of type %s', $expectedType)); - if (1 === bccomp($amount, '0')) { - // more than zero. - $expectedType = AccountType::REVENUE; - Log::debug(sprintf('Because amount is %s, will instead search for accounts of type %s', $amount, $expectedType)); - } - - // append expected types with liability types: - $expectedTypes = [$expectedType, AccountType::LOAN, AccountType::DEBT, AccountType::MORTGAGE]; - - - if ((int)$accountId > 0) { - // find any account with this ID: - $result = $this->repository->findNull($accountId); - if (null !== $result && (in_array($result->accountType->type, $expectedTypes, true) || $result->accountType->type === AccountType::ASSET)) { - Log::debug(sprintf('Found account "%s" (%s) based on given ID %d. Return it!', $result->name, $result->accountType->type, $accountId)); - - return $result; - } - if (null !== $result && !in_array($result->accountType->type, $expectedTypes, true)) { - Log::warning( - sprintf( - 'Found account "%s" (%s) based on given ID %d, but need a %s. Return nothing.', $result->name, $result->accountType->type, $accountId, - $expectedType - ) - ); - } - } - // if result is not null, system has found an account - // but it's of the wrong type. If we dont have a name, use - // the result's name, iban in the search below. - if (null !== $result && '' === (string)($data['name'] ?? '')) { - Log::debug(sprintf('Will search for account with name "%s" instead of NULL.', $result->name)); - $data['name'] = $result->name; - } - if (null !== $result && '' !== (string)$result->iban && '' === ($data['iban'] ?? '')) { - Log::debug(sprintf('Will search for account with IBAN "%s" instead of NULL.', $result->iban)); - $data['iban'] = $result->iban; - } - - // first search for $expectedType, then find asset: - $searchTypes = [$expectedType, AccountType::ASSET, AccountType::DEBT, AccountType::MORTGAGE, AccountType::LOAN]; - foreach ($searchTypes as $type) { - // find by (respectively): - // IBAN, accountNumber, name, - $fields = ['iban' => 'findByIbanNull', 'number' => 'findByAccountNumber', 'name' => 'findByName']; - foreach ($fields as $field => $function) { - $value = (string)($data[$field] ?? ''); - if ('' === $value) { - Log::debug(sprintf('Array does not contain a value for %s. Continue', $field)); - continue; - } - Log::debug(sprintf('Will search for account of type "%s" using %s() and argument "%s".', $type, $function, $value)); - $result = $this->repository->$function($value, [$type]); - if (null !== $result) { - Log::debug(sprintf('Found result: Account #%d, named "%s"', $result->id, $result->name)); - - return $result; - } - } - } - // not found? Create it! - $creation = [ - 'name' => $data['name'] ?? '(no name)', - 'iban' => $data['iban'] ?? null, - 'account_number' => $data['number'] ?? null, - 'account_type_id' => null, - 'account_type' => $expectedType, - 'active' => true, - 'BIC' => $data['bic'] ?? null, - ]; - Log::debug('Will try to store a new account: ', $creation); - - return $this->repository->store($creation); - } - - /** - * @param User $user - */ - public function setUser(User $user): void - { - $this->user = $user; - $this->repository = app(AccountRepositoryInterface::class); - $this->repository->setUser($user); - - } -} diff --git a/app/Support/Import/Routine/FinTS/StageImportDataHandler.php b/app/Support/Import/Routine/FinTS/StageImportDataHandler.php deleted file mode 100644 index e2a0bf416d..0000000000 --- a/app/Support/Import/Routine/FinTS/StageImportDataHandler.php +++ /dev/null @@ -1,193 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\FinTS; - - -use Fhp\Model\StatementOfAccount\Transaction; -use Fhp\Model\StatementOfAccount\Transaction as FinTSTransaction; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account as LocalAccount; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionType; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Support\FinTS\FinTS; -use FireflyIII\Support\FinTS\MetadataParser; -use FireflyIII\Support\Import\Routine\File\OpposingAccountMapper; -use Illuminate\Support\Facades\Log; - -/** - * - * Class StageImportDataHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageImportDataHandler -{ - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var ImportJob */ - private $importJob; - /** @var OpposingAccountMapper */ - private $mapper; - /** @var ImportJobRepositoryInterface */ - private $repository; - /** @var array */ - private $transactions; - - /** - * @return array - */ - public function getTransactions(): array - { - return $this->transactions; - } - - /** - * @throws FireflyException - */ - public function run(): void - { - Log::debug('Now in StageImportDataHandler::run()'); - - $localAccount = $this->accountRepository->findNull((int)$this->importJob->configuration['local_account']); - if (null === $localAccount) { - throw new FireflyException(sprintf('Cannot find Firefly account with id #%d ', $this->importJob->configuration['local_account'])); - } - $finTS = app(FinTS::class, ['config' => $this->importJob->configuration]); - $fintTSAccount = $finTS->getAccount($this->importJob->configuration['fints_account']); - $statementOfAccount = $finTS->getStatementOfAccount( - $fintTSAccount, new \DateTime($this->importJob->configuration['from_date']), new \DateTime($this->importJob->configuration['to_date']) - ); - $collection = []; - foreach ($statementOfAccount->getStatements() as $statement) { - foreach ($statement->getTransactions() as $transaction) { - $collection[] = $this->convertTransaction($transaction, $localAccount); - } - } - - $this->transactions = $collection; - } - - /** - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->transactions = []; - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->mapper = app(OpposingAccountMapper::class); - $this->mapper->setUser($importJob->user); - $this->repository->setUser($importJob->user); - $this->accountRepository->setUser($importJob->user); - } - - /** - * @param FinTSTransaction $transaction - * @param LocalAccount $source - * - * @return array - */ - private function convertTransaction(FinTSTransaction $transaction, LocalAccount $source): array - { - Log::debug(sprintf('Start converting transaction %s', $transaction->getDescription1())); - - $amount = (string)$transaction->getAmount(); - $debitOrCredit = $transaction->getCreditDebit(); - // assume deposit. - $type = TransactionType::DEPOSIT; - Log::debug(sprintf('Amount is %s', $amount)); - - // inverse if not. - if ($debitOrCredit !== Transaction::CD_CREDIT) { - $type = TransactionType::WITHDRAWAL; - $amount = bcmul($amount, '-1'); - } - - $destination = $this->mapper->map( - null, - $amount, - ['iban' => $transaction->getAccountNumber(), 'name' => $transaction->getName()] - ); - if ($debitOrCredit === Transaction::CD_CREDIT) { - [$source, $destination] = [$destination, $source]; - } - - if ($source->accountType->type === AccountType::ASSET && $destination->accountType->type === AccountType::ASSET) { - $type = TransactionType::TRANSFER; - Log::debug('Both are assets, will make transfer.'); - } - - $metadataParser = new MetadataParser(); - $description = $metadataParser->getDescription($transaction); - - $storeData = [ - 'user' => $this->importJob->user_id, - 'type' => $type, - 'date' => $transaction->getValutaDate()->format('Y-m-d'), - 'description' => null, - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - 'bill_id' => null, - 'bill_name' => null, - 'tags' => [], - 'internal_reference' => null, - 'external_id' => null, - 'notes' => null, - 'bunq_payment_id' => null, - 'original-source' => sprintf('fints-v%s', config('firefly.version')), - 'transactions' => [ - // single transaction: - [ - 'type' => $type, - 'description' => $description, - 'date' => $transaction->getValutaDate()->format('Y-m-d'), - 'amount' => $amount, - 'currency_id' => null, - 'currency_code' => 'EUR', - 'foreign_amount' => null, - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - 'budget_id' => null, - 'budget_name' => null, - 'category_id' => null, - 'category_name' => null, - 'source_id' => $source->id, - 'source_name' => null, - 'destination_id' => $destination->id, - 'destination_name' => null, - 'reconciled' => false, - 'identifier' => 0, - ], - ], - ]; - - return $storeData; - } -} diff --git a/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php b/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php deleted file mode 100644 index d3dd29973d..0000000000 --- a/app/Support/Import/Routine/Spectre/StageAuthenticatedHandler.php +++ /dev/null @@ -1,153 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Spectre; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Spectre\Object\Account; -use FireflyIII\Services\Spectre\Object\Login; -use FireflyIII\Services\Spectre\Request\ListAccountsRequest; -use FireflyIII\Services\Spectre\Request\ListLoginsRequest; -use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait; -use Log; - -/** - * Class StageAuthenticatedHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageAuthenticatedHandler -{ - use GetSpectreCustomerTrait; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * User has selected a login (a bank). Will grab all accounts from this bank. - * Then make user pick some to import from. - * - * @throws FireflyException - */ - public function run(): void - { - Log::debug('Now in StageAuthenticatedHandler::run()'); - // grab a list of logins. - $config = $this->importJob->configuration; - $logins = $config['all-logins'] ?? []; - Log::debug(sprintf('%d logins in config', count($logins))); - if (0 === count($logins)) { - // get logins from Spectre. - $logins = $this->getLogins(); - $config['all-logins'] = $logins; - } - - $selectedLogin = $config['selected-login'] ?? 0; - $login = null; - Log::debug(sprintf('$selectedLogin is %d', $selectedLogin)); - foreach ($logins as $loginArray) { - $loginId = $loginArray['id'] ?? -1; - if ($loginId === $selectedLogin) { - $login = new Login($loginArray); - Log::debug(sprintf('Selected login "%s" ("%s") which is in the array with logins.', $login->getProviderName(), $login->getCountryCode())); - } - } - if (null === $login) { - $login = new Login($logins[0]); - Log::debug(sprintf('Login is null, simply use the first one "%s" ("%s") from the array.', $login->getProviderName(), $login->getCountryCode())); - } - - // with existing login we can grab accounts from this login. - $accounts = $this->getAccounts($login); - $config['accounts'] = []; - /** @var Account $account */ - foreach ($accounts as $account) { - Log::debug(sprintf('Found account #%d ("%s") within Login.', $account->getId(), $account->getName())); - $config['accounts'][] = $account->toArray(); - } - $this->repository->setConfiguration($this->importJob, $config); - - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } - - /** - * @param Login $login - * - * @return array - * @throws FireflyException - */ - private function getAccounts(Login $login): array - { - Log::debug(sprintf('Now in StageAuthenticatedHandler::getAccounts() for login #%d', $login->getId())); - /** @var ListAccountsRequest $request */ - $request = app(ListAccountsRequest::class); - $request->setUser($this->importJob->user); - $request->setLogin($login); - $request->call(); - $accounts = $request->getAccounts(); - Log::debug(sprintf('Found %d accounts using login', count($accounts))); - - return $accounts; - } - - /** - * @return array - * @throws FireflyException - */ - private function getLogins(): array - { - Log::debug('Now in StageAuthenticatedHandler::getLogins().'); - $customer = $this->getCustomer($this->importJob); - - /** @var ListLoginsRequest $request */ - $request = app(ListLoginsRequest::class); - $request->setUser($this->importJob->user); - $request->setCustomer($customer); - $request->call(); - $logins = $request->getLogins(); - $return = []; - - Log::debug(sprintf('Found %d logins in users Spectre account.', count($logins))); - - /** @var Login $login */ - foreach ($logins as $login) { - $return[] = $login->toArray(); - } - - return $return; - } - - -} diff --git a/app/Support/Import/Routine/Spectre/StageImportDataHandler.php b/app/Support/Import/Routine/Spectre/StageImportDataHandler.php deleted file mode 100644 index 64e9796e2f..0000000000 --- a/app/Support/Import/Routine/Spectre/StageImportDataHandler.php +++ /dev/null @@ -1,291 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Spectre; - - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account as LocalAccount; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Spectre\Object\Account as SpectreAccount; -use FireflyIII\Services\Spectre\Object\Transaction as SpectreTransaction; -use FireflyIII\Services\Spectre\Request\ListTransactionsRequest; -use FireflyIII\Support\Import\Routine\File\OpposingAccountMapper; -use Log; - -/** - * Class StageImportDataHandler - * @deprecated - * @codeCoverageIgnore - * - */ -class StageImportDataHandler -{ - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var ImportJob */ - private $importJob; - /** @var OpposingAccountMapper */ - private $mapper; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * @throws FireflyException - */ - public function run(): void - { - Log::debug('Now in StageImportDataHandler::run()'); - $config = $this->importJob->configuration; - $accounts = $config['accounts'] ?? []; - Log::debug(sprintf('Count of accounts in array is %d', count($accounts))); - if (0 === count($accounts)) { - throw new FireflyException('There are no accounts in this import job. Cannot continue.'); // @codeCoverageIgnore - } - $toImport = $config['account_mapping'] ?? []; - $totalSet = [[]]; - foreach ($toImport as $spectreId => $localId) { - if ((int)$localId > 0) { - Log::debug(sprintf('Will get transactions from Spectre account #%d and save them in Firefly III account #%d', $spectreId, $localId)); - $spectreAccount = $this->getSpectreAccount((int)$spectreId); - $localAccount = $this->getLocalAccount((int)$localId); - $merge = $this->getTransactions($spectreAccount, $localAccount); - $totalSet[] = $merge; - Log::debug( - sprintf('Found %d transactions in account "%s" (%s)', count($merge), $spectreAccount->getName(), $spectreAccount->getCurrencyCode()) - ); - continue; - } - Log::debug(sprintf('Local account is = zero, will not import from Spectr account with ID #%d', $spectreId)); - } - $totalSet = array_merge(...$totalSet); - Log::debug(sprintf('Found %d transactions in total.', count($totalSet))); - - $this->repository->setTransactions($this->importJob, $totalSet); - } - - - /** - * @param ImportJob $importJob - * - * @return void - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->mapper = app(OpposingAccountMapper::class); - $this->accountRepository->setUser($importJob->user); - $this->repository->setUser($importJob->user); - $this->mapper->setUser($importJob->user); - } - - /** - * @param array $transactions - * @param SpectreAccount $spectreAccount - * @param LocalAccount $originalSource - * - * @return array - * - */ - private function convertToArray(array $transactions, SpectreAccount $spectreAccount, LocalAccount $originalSource): array - { - $array = []; - $total = count($transactions); - Log::debug(sprintf('Now in StageImportDataHandler::convertToArray() with count %d', count($transactions))); - /** @var SpectreTransaction $transaction */ - foreach ($transactions as $index => $transaction) { - Log::debug(sprintf('Now creating array for transaction %d of %d', $index + 1, $total)); - $extra = []; - if (null !== $transaction->getExtra()) { - $extra = $transaction->getExtra()->toArray(); - } - $destinationData = $transaction->getOpposingAccountData(); - $amount = $transaction->getAmount(); - $source = $originalSource; - $destination = $this->mapper->map(null, $amount, $destinationData); - $notes = trans('import.imported_from_account', ['account' => $spectreAccount->getName()]) . ' ' . "\n"; - $foreignAmount = null; - $foreignCurrencyCode = null; - - $currencyCode = $transaction->getCurrencyCode(); - $type = 'withdrawal'; - // switch source and destination if amount is greater than zero. - if (1 === bccomp($amount, '0')) { - [$source, $destination] = [$destination, $source]; - $type = 'deposit'; - } - - Log::debug(sprintf('Mapped destination to #%d ("%s")', $destination->id, $destination->name)); - Log::debug(sprintf('Set source to #%d ("%s")', $source->id, $source->name)); - - // put some data in tags: - $tags = []; - $tags[] = $transaction->getMode(); - $tags[] = $transaction->getStatus(); - if ($transaction->isDuplicated()) { - $tags[] = 'possibly-duplicated'; - } - - // get extra fields: - foreach ($extra as $key => $value) { - if ('' === (string)$value) { - continue; - } - switch ($key) { - case 'original_category': - case 'original_subcategory': - case 'customer_category_code': - case 'customer_category_name': - $tags[] = $value; - break; - case 'original_amount': - $foreignAmount = $value; - Log::debug(sprintf('Foreign amount is now %s', $value)); - break; - case 'original_currency_code': - $foreignCurrencyCode = $value; - Log::debug(sprintf('Foreign currency code is now %s', $value)); - break; - case 'time': - // ignore time because it breaks the duplicate detector. - break; - default: - $notes .= $key . ': ' . $value . ' ' . "\n"; // for newline in Markdown. - } - } - - $entry = [ - // transaction data: - 'transactions' => [ - [ - 'date' => $transaction->getMadeOn()->format('Y-m-d'), - 'tags' => $tags, - 'user' => $this->importJob->user_id, - 'notes' => trim($notes), - - // all custom fields: - 'external_id' => (string)$transaction->getId(), - - // journal data: - 'description' => $transaction->getDescription(), - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - 'bill_id' => null, - 'bill_name' => null, - 'original-source' => sprintf('spectre-v%s', config('firefly.version')), - 'type' => $type, - 'currency_id' => null, - 'currency_code' => $currencyCode, - 'amount' => $amount, - 'budget_id' => null, - 'budget_name' => null, - 'category_id' => null, - 'category_name' => $transaction->getCategory(), - 'source_id' => $source->id, - 'source_name' => null, - 'destination_id' => $destination->id, - 'destination_name' => null, - 'foreign_currency_id' => null, - 'foreign_currency_code' => $foreignCurrencyCode, - 'foreign_amount' => $foreignAmount, - 'reconciled' => false, - 'identifier' => 0, - ], - ], - ]; - $array[] = $entry; - } - Log::debug(sprintf('Return %d entries', count($array))); - - return $array; - } - - /** - * @param int $accountId - * - * @return LocalAccount - * @throws FireflyException - */ - private function getLocalAccount(int $accountId): LocalAccount - { - $account = $this->accountRepository->findNull($accountId); - if (null === $account) { - throw new FireflyException(sprintf('Cannot find Firefly III asset account with ID #%d. Job must stop now.', $accountId)); // @codeCoverageIgnore - } - if (!in_array($account->accountType->type, [AccountType::ASSET, AccountType::LOAN, AccountType::MORTGAGE, AccountType::DEBT], true)) { - throw new FireflyException( - sprintf('Account with ID #%d is not an asset/loan/mortgage/debt account. Job must stop now.', $accountId) - ); // @codeCoverageIgnore - } - - return $account; - } - - /** - * @param int $accountId - * - * @return SpectreAccount - * @throws FireflyException - */ - private function getSpectreAccount(int $accountId): SpectreAccount - { - $config = $this->importJob->configuration; - $accounts = $config['accounts'] ?? []; - foreach ($accounts as $account) { - $spectreId = (int)($account['id'] ?? 0.0); - if ($spectreId === $accountId) { - return new SpectreAccount($account); - } - } - throw new FireflyException(sprintf('Cannot find Spectre account with ID #%d in configuration. Job will exit.', $accountId)); // @codeCoverageIgnore - } - - /** - * @param SpectreAccount $spectreAccount - * @param LocalAccount $localAccount - * - * @return array - * @throws FireflyException - */ - private function getTransactions(SpectreAccount $spectreAccount, LocalAccount $localAccount): array - { - // grab all transactions - /** @var ListTransactionsRequest $request */ - $request = app(ListTransactionsRequest::class); - $request->setUser($this->importJob->user); - - $request->setAccount($spectreAccount); - $request->call(); - - $transactions = $request->getTransactions(); - - return $this->convertToArray($transactions, $spectreAccount, $localAccount); - } - - -} diff --git a/app/Support/Import/Routine/Spectre/StageNewHandler.php b/app/Support/Import/Routine/Spectre/StageNewHandler.php deleted file mode 100644 index 74360cc154..0000000000 --- a/app/Support/Import/Routine/Spectre/StageNewHandler.php +++ /dev/null @@ -1,109 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Spectre; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Spectre\Object\Login; -use FireflyIII\Services\Spectre\Request\ListLoginsRequest; -use FireflyIII\Support\Import\Information\GetSpectreCustomerTrait; -use Log; - -/** - * Class StageNewHandler - * @deprecated - * @codeCoverageIgnore - * - */ -class StageNewHandler -{ - use GetSpectreCustomerTrait; - /** @var int */ - private $countLogins = 0; - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * @codeCoverageIgnore - * @return int - */ - public function getCountLogins(): int - { - return $this->countLogins; - } - - - /** - * Tasks for this stage: - * - * - List all of the users logins. - * - If zero, return to "get-token" stage and make user make a login. That stage redirects here. - * - If one or more, list and let user select. - * - * @throws FireflyException - */ - public function run(): void - { - Log::debug('Now in ManageLoginsHandler::run()'); - $customer = $this->getCustomer($this->importJob); - $config = $this->repository->getConfiguration($this->importJob); - - Log::debug('Going to get a list of logins.'); - /** @var ListLoginsRequest $request */ - $request = app(ListLoginsRequest::class); - $request->setUser($this->importJob->user); - $request->setCustomer($customer); - $request->call(); - - $list = $request->getLogins(); - - // count is zero? - $this->countLogins = count($list); - Log::debug(sprintf('Number of logins is %d', $this->countLogins)); - if ($this->countLogins > 0) { - $store = []; - /** @var Login $login */ - foreach ($list as $login) { - $store[] = $login->toArray(); - } - - $config['all-logins'] = $store; - $this->repository->setConfiguration($this->importJob, $config); - Log::debug('Stored all logins in configuration.'); - } - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/Routine/Ynab/GetAccountsHandler.php b/app/Support/Import/Routine/Ynab/GetAccountsHandler.php deleted file mode 100644 index b51aca4ed7..0000000000 --- a/app/Support/Import/Routine/Ynab/GetAccountsHandler.php +++ /dev/null @@ -1,82 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Ynab; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Ynab\Request\GetAccountsRequest; - -/** - * Class GetAccountsHandler - * @deprecated - * @codeCoverageIgnore - */ -class GetAccountsHandler -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Get list of accounts for the selected budget. - * - * @throws FireflyException - */ - public function run(): void - { - - $config = $this->repository->getConfiguration($this->importJob); - $selectedBudget = $config['selected_budget'] ?? ''; - if ('' === $selectedBudget) { - $firstBudget = $config['budgets'][0] ?? false; - if (false === $firstBudget) { - throw new FireflyException('The configuration contains no budget. Erroring out.'); - } - $selectedBudget = $firstBudget['id']; - $config['selected_budget'] = $selectedBudget; - } - $token = $config['access_token']; - $request = new GetAccountsRequest; - $request->budgetId = $selectedBudget; - $request->setAccessToken($token); - $request->call(); - $config['accounts'] = $request->accounts; - $this->repository->setConfiguration($this->importJob, $config); - if (0 === count($config['accounts'])) { - throw new FireflyException('This budget contains zero accounts.'); - } - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/Routine/Ynab/ImportDataHandler.php b/app/Support/Import/Routine/Ynab/ImportDataHandler.php deleted file mode 100644 index 1e8d69b534..0000000000 --- a/app/Support/Import/Routine/Ynab/ImportDataHandler.php +++ /dev/null @@ -1,290 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Ynab; - - -use Carbon\Carbon; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\Account; -use FireflyIII\Models\AccountType; -use FireflyIII\Models\ImportJob; -use FireflyIII\Models\TransactionCurrency; -use FireflyIII\Repositories\Account\AccountRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Ynab\Request\GetTransactionsRequest; -use FireflyIII\Support\Import\Routine\File\OpposingAccountMapper; -use Log; - -/** - * Class ImportDataHandler - * @deprecated - * @codeCoverageIgnore - */ -class ImportDataHandler -{ - /** @var AccountRepositoryInterface */ - private $accountRepository; - /** @var TransactionCurrency */ - private $defaultCurrency; - /** @var ImportJob */ - private $importJob; - /** @var OpposingAccountMapper */ - private $mapper; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Get list of accounts for the selected budget. - * - * @throws FireflyException - */ - public function run(): void - { - $config = $this->repository->getConfiguration($this->importJob); - $this->defaultCurrency = app('amount')->getDefaultCurrencyByUser($this->importJob->user); - $token = $config['access_token']; - // make request for each mapping: - $mapping = $config['mapping'] ?? []; - $total = [[]]; - - /** - * @var string $ynabId - * @var string $localId - */ - foreach ($mapping as $ynabId => $localId) { - $localAccount = $this->getLocalAccount((int)$localId); - $transactions = $this->getTransactions($token, $ynabId); - $converted = $this->convertToArray($transactions, $localAccount); - $total[] = $converted; - } - - $totalSet = array_merge(...$total); - Log::debug(sprintf('Found %d transactions in total.', count($totalSet))); - $this->repository->setTransactions($this->importJob, $totalSet); - - // assuming this works, store today's date as a preference - // (combined with the budget from which FF3 imported) - $budgetId = $this->getSelectedBudget()['id'] ?? ''; - if ('' !== $budgetId) { - app('preferences')->set('ynab_' . $budgetId, Carbon::now()->format('Y-m-d')); - } - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->accountRepository = app(AccountRepositoryInterface::class); - $this->mapper = app(OpposingAccountMapper::class); - $this->accountRepository->setUser($importJob->user); - $this->repository->setUser($importJob->user); - $this->mapper->setUser($importJob->user); - } - - /** - * @param array $transactions - * @param Account $localAccount - * - * @return array - * @throws FireflyException - */ - private function convertToArray(array $transactions, Account $localAccount): array - { - $config = $this->repository->getConfiguration($this->importJob); - $array = []; - $total = count($transactions); - $budget = $this->getSelectedBudget(); - Log::debug(sprintf('Now in StageImportDataHandler::convertToArray() with count %d', count($transactions))); - /** @var array $transaction */ - foreach ($transactions as $index => $transaction) { - $description = $transaction['memo'] ?? '(empty)'; - Log::debug(sprintf('Now creating array for transaction %d of %d ("%s")', $index + 1, $total, $description)); - $amount = (string)($transaction['amount'] ?? 0); - if ('0' === $amount) { - Log::debug(sprintf('Amount is zero (%s), skip this transaction.', $amount)); - continue; - } - Log::debug(sprintf('Amount detected is %s', $amount)); - $source = $localAccount; - $type = 'withdrawal'; - $tags = [ - $transaction['cleared'] ?? '', - $transaction['approved'] ? 'approved' : 'not-approved', - $transaction['flag_color'] ?? '', - ]; - $possibleDestinationId = null; - if (null !== $transaction['transfer_account_id']) { - // indication that it is a transfer. - $possibleDestinationId = $config['mapping'][$transaction['transfer_account_id']] ?? null; - Log::debug(sprintf('transfer_account_id has value %s', $transaction['transfer_account_id'])); - Log::debug(sprintf('Can map this to the following FF3 asset account: %d', $possibleDestinationId)); - $type = 'transfer'; - - } - - $destinationData = [ - 'name' => str_replace('Transfer: ', '', $transaction['payee_name']), - 'iban' => null, - 'number' => $transaction['payee_id'], - 'bic' => null, - ]; - - $destination = $this->mapper->map($possibleDestinationId, $amount, $destinationData); - if (1 === bccomp($amount, '0')) { - [$source, $destination] = [$destination, $source]; - $type = 'transfer' === $type ? 'transfer' : 'deposit'; - Log::debug(sprintf('Amount is %s, so switch source/dest and make this a %s', $amount, $type)); - } - - Log::debug(sprintf('Final source account: #%d ("%s")', $source->id, $source->name)); - Log::debug(sprintf('Final destination account: #%d ("%s")', $destination->id, $destination->name)); - - $entry = [ - 'type' => $type, - 'date' => $transaction['date'] ?? date('Y-m-d'), - 'tags' => $tags, - 'user' => $this->importJob->user_id, - 'notes' => null, - - // all custom fields: - 'external_id' => $transaction['id'] ?? '', - - // journal data: - 'description' => $description, - 'piggy_bank_id' => null, - 'piggy_bank_name' => null, - 'bill_id' => null, - 'bill_name' => null, - 'original-source' => sprintf('ynab-v%s', config('firefly.version')), - - // transaction data: - 'transactions' => [ - [ - 'type' => $type, - 'date' => $transaction['date'] ?? date('Y-m-d'), - 'tags' => $tags, - 'user' => $this->importJob->user_id, - 'notes' => null, - 'currency_id' => null, - 'currency_code' => $budget['currency_code'] ?? $this->defaultCurrency->code, - 'amount' => bcdiv((string)$transaction['amount'], '1000'), - 'budget_id' => null, - 'original-source' => sprintf('ynab-v%s', config('firefly.version')), - 'budget_name' => null, - 'category_id' => null, - 'category_name' => $transaction['category_name'], - 'source_id' => $source->id, - 'source_name' => null, - // all custom fields: - 'external_id' => $transaction['id'] ?? '', - - // journal data: - 'description' => $description, - 'destination_id' => $destination->id, - 'destination_name' => null, - 'foreign_currency_id' => null, - 'foreign_currency_code' => null, - 'foreign_amount' => null, - 'reconciled' => false, - 'identifier' => 0, - ], - ], - ]; - Log::debug(sprintf('Done with entry #%d', $index)); - $array[] = $entry; - } - - return $array; - } - - /** - * @param int $accountId - * - * @return Account - * @throws FireflyException - */ - private function getLocalAccount(int $accountId): Account - { - $account = $this->accountRepository->findNull($accountId); - if (null === $account) { - throw new FireflyException(sprintf('Cannot find Firefly III asset account with ID #%d. Job must stop now.', $accountId)); // @codeCoverageIgnore - } - if ($account->accountType->type !== AccountType::ASSET) { - throw new FireflyException(sprintf('Account with ID #%d is not an asset account. Job must stop now.', $accountId)); // @codeCoverageIgnore - } - - return $account; - } - - /** - * @return array - * @throws FireflyException - */ - private function getSelectedBudget(): array - { - $config = $this->repository->getConfiguration($this->importJob); - $budgets = $config['budgets'] ?? []; - $selected = $config['selected_budget'] ?? ''; - - if ('' === $selected) { - $firstBudget = $config['budgets'][0] ?? false; - if (false === $firstBudget) { - throw new FireflyException('The configuration contains no budget. Erroring out.'); - } - $selected = $firstBudget['id']; - } - - foreach ($budgets as $budget) { - if ($budget['id'] === $selected) { - return $budget; - } - } - - return $budgets[0] ?? []; - } - - /** - * @param string $token - * @param string $account - * - * @return array - * @throws FireflyException - */ - private function getTransactions(string $token, string $account): array - { - $budget = $this->getSelectedBudget(); - $request = new GetTransactionsRequest; - $request->budgetId = $budget['id']; - $request->accountId = $account; - - // todo grab latest date for $ynabId - $request->setAccessToken($token); - $request->call(); - - return $request->transactions; - } -} diff --git a/app/Support/Import/Routine/Ynab/StageGetAccessHandler.php b/app/Support/Import/Routine/Ynab/StageGetAccessHandler.php deleted file mode 100644 index c775a00487..0000000000 --- a/app/Support/Import/Routine/Ynab/StageGetAccessHandler.php +++ /dev/null @@ -1,110 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Ynab; - -use Exception; -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\GuzzleException; -use Log; -use RuntimeException; - -/** - * Class StageGetAccessHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageGetAccessHandler -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * Send a token request to YNAB. Return with access token (if all goes well). - * - * @throws \Psr\Container\NotFoundExceptionInterface - * @throws \Psr\Container\ContainerExceptionInterface - * @throws FireflyException - */ - public function run(): void - { - $config = $this->repository->getConfiguration($this->importJob); - $clientId = app('preferences')->get('ynab_client_id', '')->data; - $clientSecret = app('preferences')->get('ynab_client_secret', '')->data; - $redirectUri = route('import.callback.ynab'); - $code = $config['auth_code']; - $uri = sprintf( - 'https://app.youneedabudget.com/oauth/token?client_id=%s&client_secret=%s&redirect_uri=%s&grant_type=authorization_code&code=%s', $clientId, - $clientSecret, $redirectUri, $code - ); - $client = new Client; - try { - $res = $client->request('POST', $uri); - } catch (GuzzleException|Exception $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - throw new FireflyException($e->getMessage()); - } - $statusCode = $res->getStatusCode(); - try { - $content = trim($res->getBody()->getContents()); - } catch (RuntimeException $e) { - Log::error($e->getMessage()); - Log::error($e->getTraceAsString()); - throw new FireflyException($e->getMessage()); - } - - $json = json_decode($content, true) ?? []; - Log::debug(sprintf('Status code from YNAB is %d', $statusCode)); - Log::debug(sprintf('Body of result is %s', $content), $json); - - // store refresh token (if present?) as preference - // store token in job: - $configuration = $this->repository->getConfiguration($this->importJob); - $configuration['access_token'] = $json['access_token']; - $configuration['access_token_expires'] = (int)$json['created_at'] + (int)$json['expires_in']; - $this->repository->setConfiguration($this->importJob, $configuration); - - Log::debug('end of StageGetAccessHandler::run()'); - - $refreshToken = (string)($json['refresh_token'] ?? ''); - if ('' !== $refreshToken) { - app('preferences')->set('ynab_refresh_token', $refreshToken); - } - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/Routine/Ynab/StageGetBudgetsHandler.php b/app/Support/Import/Routine/Ynab/StageGetBudgetsHandler.php deleted file mode 100644 index a0e0923966..0000000000 --- a/app/Support/Import/Routine/Ynab/StageGetBudgetsHandler.php +++ /dev/null @@ -1,77 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Ynab; - -use FireflyIII\Exceptions\FireflyException; -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; -use FireflyIII\Services\Ynab\Request\GetBudgetsRequest; -use Log; - -/** - * Class StageGetBudgetsHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageGetBudgetsHandler -{ - - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * - * @throws FireflyException - */ - public function run(): void - { - Log::debug('Now in StageGetBudgetsHandler::run()'); - // grab access token from job: - $configuration = $this->repository->getConfiguration($this->importJob); - $token = $configuration['access_token']; - $request = new GetBudgetsRequest; - $request->setAccessToken($token); - $request->call(); - - // store budgets in users preferences. - $configuration['budgets'] = $request->budgets; - $this->repository->setConfiguration($this->importJob, $configuration); - Log::debug(sprintf('Found %d budgets', count($request->budgets))); - if (0 === count($request->budgets)) { - throw new FireflyException('It seems this user has zero budgets or an error prevented Firefly III from reading them.'); - } - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/Routine/Ynab/StageGetTransactionsHandler.php b/app/Support/Import/Routine/Ynab/StageGetTransactionsHandler.php deleted file mode 100644 index be8cdd7ff1..0000000000 --- a/app/Support/Import/Routine/Ynab/StageGetTransactionsHandler.php +++ /dev/null @@ -1,57 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Ynab; - -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; - -/** - * Class StageGetTransactionsHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageGetTransactionsHandler -{ - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * - */ - public function run(): void - { - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/Import/Routine/Ynab/StageMatchAccountsHandler.php b/app/Support/Import/Routine/Ynab/StageMatchAccountsHandler.php deleted file mode 100644 index 948b64a5bb..0000000000 --- a/app/Support/Import/Routine/Ynab/StageMatchAccountsHandler.php +++ /dev/null @@ -1,59 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Support\Import\Routine\Ynab; - -use FireflyIII\Models\ImportJob; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; - -/** - * Class StageMatchAccountsHandler - * @deprecated - * @codeCoverageIgnore - */ -class StageMatchAccountsHandler -{ - - - /** @var ImportJob */ - private $importJob; - /** @var ImportJobRepositoryInterface */ - private $repository; - - /** - * - */ - public function run(): void - { - } - - /** - * @param ImportJob $importJob - */ - public function setImportJob(ImportJob $importJob): void - { - $this->importJob = $importJob; - $this->repository = app(ImportJobRepositoryInterface::class); - $this->repository->setUser($importJob->user); - } -} diff --git a/app/Support/ParseDateString.php b/app/Support/ParseDateString.php index 1b45b4defb..67a1bbf6f9 100644 --- a/app/Support/ParseDateString.php +++ b/app/Support/ParseDateString.php @@ -35,6 +35,7 @@ class ParseDateString */ public function parseDate(string $date): Carbon { + $date = strtolower($date); // parse keywords: if (in_array($date, $this->keywords, true)) { return $this->parseKeyword($date); @@ -48,18 +49,189 @@ class ParseDateString // if + or -: if (0 === strpos($date, '+') || 0 === strpos($date, '-')) { + return $this->parseRelativeDate($date); } + if ('xxxx-xx-xx' === strtolower($date)) { + throw new FireflyException(sprintf('[a]Not a recognised date format: "%s"', $date)); + } + // can't do a partial year: + $substrCount = substr_count(substr($date, 0, 4), 'x', 0); + if (10 === strlen($date) && $substrCount > 0 && $substrCount < 4) { + throw new FireflyException(sprintf('[b]Not a recognised date format: "%s"', $date)); + } - throw new FireflyException('Not recognised.'); + // maybe a date range + if (10 === strlen($date) && (false !== strpos($date, 'xx') || false !== strpos($date, 'xxxx'))) { + Log::debug(sprintf('[c]Detected a date range ("%s"), return a fake date.', $date)); + // very lazy way to parse the date without parsing it, because this specific function + // cant handle date ranges. + return new Carbon('1984-09-17'); + } + + throw new FireflyException(sprintf('[d]Not a recognised date format: "%s"', $date)); } + /** + * @param string $date + * + * @return bool + */ + public function isDateRange(string $date): bool + { + $date = strtolower($date); + // not 10 chars: + if (10 !== strlen($date)) { + return false; + } + // all x'es + if ('xxxx-xx-xx' === strtolower($date)) { + return false; + } + // no x'es + if (false === strpos($date, 'xx') && false === strpos($date, 'xxxx')) { + return false; + } + + return true; + } + + /** + * @param string $date + * @param Carbon $journalDate + * + * @return array + */ + public function parseRange(string $date, Carbon $journalDate): array + { + // several types of range can be submitted + switch (true) { + default: + break; + case $this->isDayRange($date): + return $this->parseDayRange($date, $journalDate); + case $this->isMonthRange($date): + return $this->parseMonthRange($date, $journalDate); + case $this->isYearRange($date): + return $this->parseYearRange($date, $journalDate); + case $this->isMonthDayRange($date): + return $this->parseMonthDayRange($date, $journalDate); + case $this->isDayYearRange($date): + return $this->parseDayYearRange($date, $journalDate); + case $this->isMonthYearRange($date): + return $this->parseMonthYearRange($date, $journalDate); + } + + return [ + 'start' => new Carbon('1984-09-17'), + 'end' => new Carbon('1984-09-17'), + ]; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isDayRange(string $date): bool + { + // if regex for xxxx-xx-DD: + $pattern = '/^xxxx-xx-(0[1-9]|[12][\d]|3[01])$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a day range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a day range.', $date)); + + return false; + } + + /** + * @param string $date + * @param Carbon $journalDate + * + * @return array + */ + protected function parseDayRange(string $date, Carbon $journalDate): array + { + // format of string is xxxx-xx-DD + $validDate = str_replace(['xxxx'], [$journalDate->year], $date); + $validDate = str_replace(['xx'], [$journalDate->format('m')], $validDate); + Log::debug(sprintf('parseDayRange: Parsed "%s" into "%s"', $date, $validDate)); + $start = Carbon::createFromFormat('Y-m-d', $validDate)->startOfDay(); + $end = Carbon::createFromFormat('Y-m-d', $validDate)->endOfDay(); + + return [ + 'start' => $start, + 'end' => $end, + ]; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isMonthRange(string $date): bool + { + // if regex for xxxx-MM-xx: + $pattern = '/^xxxx-(0[1-9]|1[012])-xx$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a month range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a month range.', $date)); + + return false; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isMonthYearRange(string $date): bool + { + // if regex for YYYY-MM-xx: + $pattern = '/^(19|20)\d\d-(0[1-9]|1[012])-xx$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a month/year range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a month/year range.', $date)); + + return false; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isYearRange(string $date): bool + { + // if regex for YYYY-xx-xx: + $pattern = '/^(19|20)\d\d-xx-xx$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a year range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a year range.', $date)); + + return false; + } + + /** * @param string $date * * @return Carbon */ - private function parseDefaultDate(string $date): Carbon + protected function parseDefaultDate(string $date): Carbon { return Carbon::createFromFormat('Y-m-d', $date); } @@ -69,7 +241,7 @@ class ParseDateString * * @return Carbon */ - private function parseKeyword(string $keyword): Carbon + protected function parseKeyword(string $keyword): Carbon { $today = Carbon::today()->startOfDay(); switch ($keyword) { @@ -99,12 +271,65 @@ class ParseDateString } } + /** + * @param string $date + * @param Carbon $journalDate + * + * @return array + */ + protected function parseMonthRange(string $date, Carbon $journalDate): array + { + // because 31 would turn February into March unexpectedly and the exact day is irrelevant here. + $day = $journalDate->format('d'); + if ((int) $day > 28) { + $day = '28'; + } + + // format of string is xxxx-MM-xx + $validDate = str_replace(['xxxx'], [$journalDate->year], $date); + $validDate = str_replace(['xx'], [$day], $validDate); + Log::debug(sprintf('parseMonthRange: Parsed "%s" into "%s"', $date, $validDate)); + $start = Carbon::createFromFormat('Y-m-d', $validDate)->startOfMonth(); + $end = Carbon::createFromFormat('Y-m-d', $validDate)->endOfMonth(); + + return [ + 'start' => $start, + 'end' => $end, + ]; + } + + /** + * @param string $date + * @param Carbon $journalDate + * + * @return array + */ + protected function parseMonthYearRange(string $date, Carbon $journalDate): array + { + // because 31 would turn February into March unexpectedly and the exact day is irrelevant here. + $day = $journalDate->format('d'); + if ((int) $day > 28) { + $day = '28'; + } + + // format of string is YYYY-MM-xx + $validDate = str_replace(['xx'], [$day], $date); + Log::debug(sprintf('parseMonthYearRange: Parsed "%s" into "%s"', $date, $validDate)); + $start = Carbon::createFromFormat('Y-m-d', $validDate)->startOfMonth(); + $end = Carbon::createFromFormat('Y-m-d', $validDate)->endOfMonth(); + + return [ + 'start' => $start, + 'end' => $end, + ]; + } + /** * @param string $date * * @return Carbon */ - private function parseRelativeDate(string $date): Carbon + protected function parseRelativeDate(string $date): Carbon { Log::debug(sprintf('Now in parseRelativeDate("%s")', $date)); $parts = explode(' ', $date); @@ -154,4 +379,106 @@ class ParseDateString return $today; } + /** + * @param string $date + * @param Carbon $journalDate + * + * @return array + */ + protected function parseYearRange(string $date, Carbon $journalDate): array + { + // format of string is YYYY-xx-xx + // kind of a convulted way of replacing variables but I'm lazy. + $validDate = str_replace(['xx-xx'], [sprintf('%s-xx', $journalDate->format('m'))], $date); + $validDate = str_replace(['xx'], [$journalDate->format('d')], $validDate); + Log::debug(sprintf('parseYearRange: Parsed "%s" into "%s"', $date, $validDate)); + $start = Carbon::createFromFormat('Y-m-d', $validDate)->startOfYear(); + $end = Carbon::createFromFormat('Y-m-d', $validDate)->endOfYear(); + + return [ + 'start' => $start, + 'end' => $end, + ]; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isMonthDayRange(string $date): bool + { + // if regex for xxxx-MM-DD: + $pattern = '/^xxxx-(0[1-9]|1[012])-(0[1-9]|[12][\d]|3[01])$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a month/day range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a month/day range.', $date)); + + return false; + } + + /** + * @param string $date + * + * @return bool + */ + protected function isDayYearRange(string $date): bool + { + // if regex for YYYY-xx-DD: + $pattern = '/^(19|20)\d\d-xx-(0[1-9]|[12][\d]|3[01])$/'; + if (preg_match($pattern, $date)) { + Log::debug(sprintf('"%s" is a day/year range.', $date)); + + return true; + } + Log::debug(sprintf('"%s" is not a day/year range.', $date)); + + return false; + } + + /** + * @param string $date + * @param Carbon $journalDate + * + * @return array + */ + private function parseMonthDayRange(string $date, Carbon $journalDate): array + { + // Any year. + // format of string is xxxx-MM-DD + $validDate = str_replace(['xxxx'], [$journalDate->year], $date); + Log::debug(sprintf('parseMonthDayRange: Parsed "%s" into "%s"', $date, $validDate)); + $start = Carbon::createFromFormat('Y-m-d', $validDate)->startOfDay(); + $end = Carbon::createFromFormat('Y-m-d', $validDate)->endOfDay(); + + return [ + 'start' => $start, + 'end' => $end, + ]; + } + + /** + * @param string $date + * @param Carbon $journalDate + * + * @return array + */ + private function parseDayYearRange(string $date, Carbon $journalDate): array + { + // Any year. + // format of string is YYYY-xx-DD + $validDate = str_replace(['xx'], [$journalDate->format('m')], $date); + Log::debug(sprintf('parseDayYearRange: Parsed "%s" into "%s"', $date, $validDate)); + $start = Carbon::createFromFormat('Y-m-d', $validDate)->startOfDay(); + $end = Carbon::createFromFormat('Y-m-d', $validDate)->endOfDay(); + + return [ + 'start' => $start, + 'end' => $end, + ]; + } + } diff --git a/app/Support/Steam.php b/app/Support/Steam.php index c3d033aa97..0842414269 100644 --- a/app/Support/Steam.php +++ b/app/Support/Steam.php @@ -244,7 +244,8 @@ class Steam } $currentBalance = bcadd($currentBalance, $amount); - $carbon = new Carbon($entry->date); + $carbon = new Carbon($entry->date, 'UTC'); + $carbon->setTimezone(env('TZ')); $date = $carbon->format('Y-m-d'); $balances[$date] = $currentBalance; } @@ -502,7 +503,9 @@ class Steam ->get(['transactions.account_id', DB::raw('MAX(transaction_journals.date) AS max_date')]); foreach ($set as $entry) { - $list[(int)$entry->account_id] = new Carbon($entry->max_date); + $date = new Carbon($entry->max_date,'UTC'); + $date->setTimezone(env('TZ')); + $list[(int)$entry->account_id] = $date; } return $list; diff --git a/app/Support/System/GeneratesInstallationId.php b/app/Support/System/GeneratesInstallationId.php index 9dac7661eb..3ffe860b1e 100644 --- a/app/Support/System/GeneratesInstallationId.php +++ b/app/Support/System/GeneratesInstallationId.php @@ -17,9 +17,15 @@ trait GeneratesInstallationId protected function generateInstallationId(): void { $config = app('fireflyconfig')->get('installation_id', null); + + // delete if wrong UUID: + if (null !== $config && 'b2c27d92-be90-5c10-8589-005df5b314e6' === $config->data) { + $config = null; + } + if (null === $config) { - $uuid5 = Uuid::uuid5(Uuid::NAMESPACE_URL, 'firefly-iii.org'); - $uniqueId = (string) $uuid5; + $uuid4 = Uuid::uuid4(); + $uniqueId = (string) $uuid4; Log::info(sprintf('Created Firefly III installation ID %s', $uniqueId)); app('fireflyconfig')->set('installation_id', $uniqueId); } diff --git a/app/Support/Telemetry.php b/app/Support/Telemetry.php index 14ef9cc927..76e8bbd696 100644 --- a/app/Support/Telemetry.php +++ b/app/Support/Telemetry.php @@ -45,7 +45,6 @@ class Telemetry * - execute-cli-command [value] * - use-help-pages * - has-created-bill - * - do-big-import * - first-time-install * - more * diff --git a/app/TransactionRules/Triggers/DateAfter.php b/app/TransactionRules/Triggers/DateAfter.php index 71ac2cdbcf..a702bf3668 100644 --- a/app/TransactionRules/Triggers/DateAfter.php +++ b/app/TransactionRules/Triggers/DateAfter.php @@ -82,7 +82,8 @@ final class DateAfter extends AbstractTrigger implements TriggerInterface return false; } - if ($date->isAfter($ruleDate)) { + $isDateRange = $dateParser->isDateRange($this->triggerValue); + if (false === $isDateRange && $date->isAfter($ruleDate)) { Log::debug( sprintf( '%s is after %s, so return true.', @@ -93,6 +94,32 @@ final class DateAfter extends AbstractTrigger implements TriggerInterface return true; } + // could be a date range. + if ($isDateRange) { + Log::debug(sprintf('Date value is "%s", representing a range.', $this->triggerValue)); + $range = $dateParser->parseRange($this->triggerValue, $date); + if ($date->isAfter($range['end'])) { + Log::debug( + sprintf( + '%s is after [%s/%s], so return true.', + $date->format('Y-m-d H:i:s'), + $range['start']->format('Y-m-d H:i:s'), + $range['end']->format('Y-m-d H:i:s'), + ) + ); + + return true; + } + Log::debug( + sprintf( + '%s is NOT after [%s/%s], so return false.', + $date->format('Y-m-d H:i:s'), + $range['start']->format('Y-m-d H:i:s'), + $range['end']->format('Y-m-d H:i:s'), + ) + ); + return false; + } Log::debug( sprintf( diff --git a/app/TransactionRules/Triggers/DateBefore.php b/app/TransactionRules/Triggers/DateBefore.php index 0b6a6e7c40..de41f6da67 100644 --- a/app/TransactionRules/Triggers/DateBefore.php +++ b/app/TransactionRules/Triggers/DateBefore.php @@ -82,7 +82,9 @@ final class DateBefore extends AbstractTrigger implements TriggerInterface return false; } - if ($date->isBefore($ruleDate)) { + $isDateRange = $dateParser->isDateRange($this->triggerValue); + + if (false === $isDateRange && $date->isBefore($ruleDate)) { Log::debug( sprintf( '%s is before %s, so return true.', @@ -94,6 +96,35 @@ final class DateBefore extends AbstractTrigger implements TriggerInterface return true; } + // could be a date range. + if ($isDateRange) { + Log::debug(sprintf('Date value is "%s", representing a range.', $this->triggerValue)); + $range = $dateParser->parseRange($this->triggerValue, $date); + if ($date->isBefore($range['start'])) { + Log::debug( + sprintf( + '%s is before [%s/%s], so return true.', + $date->format('Y-m-d H:i:s'), + $range['start']->format('Y-m-d H:i:s'), + $range['end']->format('Y-m-d H:i:s'), + ) + ); + + return true; + } + Log::debug( + sprintf( + '%s is NOT before [%s/%s], so return false.', + $date->format('Y-m-d H:i:s'), + $range['start']->format('Y-m-d H:i:s'), + $range['end']->format('Y-m-d H:i:s'), + ) + ); + return false; + } + + + Log::debug( sprintf( '%s is NOT before %s, so return true.', diff --git a/app/TransactionRules/Triggers/DateIs.php b/app/TransactionRules/Triggers/DateIs.php index 6661b4e441..62cdeda575 100644 --- a/app/TransactionRules/Triggers/DateIs.php +++ b/app/TransactionRules/Triggers/DateIs.php @@ -82,7 +82,9 @@ final class DateIs extends AbstractTrigger implements TriggerInterface return false; } - if ($ruleDate->isSameDay($date)) { + $isDateRange = $dateParser->isDateRange($this->triggerValue); + + if (false === $isDateRange && $ruleDate->isSameDay($date)) { Log::debug( sprintf( '%s is on the same day as %s, so return true.', @@ -94,6 +96,34 @@ final class DateIs extends AbstractTrigger implements TriggerInterface return true; } + // could be a date range. + if ($isDateRange) { + Log::debug(sprintf('Date value is "%s", representing a range.', $this->triggerValue)); + $range = $dateParser->parseRange($this->triggerValue, $date); + if ($date->isAfter($range['start']) && $date->isBefore($range['end'])) { + Log::debug( + sprintf( + '%s is between [%s/%s], so return true.', + $date->format('Y-m-d H:i:s'), + $range['start']->format('Y-m-d H:i:s'), + $range['end']->format('Y-m-d H:i:s'), + ) + ); + + return true; + } + Log::debug( + sprintf( + '%s is NOT between [%s/%s], so return false.', + $date->format('Y-m-d H:i:s'), + $range['start']->format('Y-m-d H:i:s'), + $range['end']->format('Y-m-d H:i:s'), + ) + ); + + return false; + } + Log::debug( sprintf( '%s is NOT on the same day as %s, so return true.', diff --git a/app/Transformers/ImportJobTransformer.php b/app/Transformers/ImportJobTransformer.php deleted file mode 100644 index b705e766d4..0000000000 --- a/app/Transformers/ImportJobTransformer.php +++ /dev/null @@ -1,91 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace FireflyIII\Transformers; - - -use FireflyIII\Models\ImportJob; -use Log; - -/** - * Class ImportJobTransformer - * @deprecated - */ -class ImportJobTransformer extends AbstractTransformer -{ - /** - * PiggyBankTransformer constructor. - * - * @codeCoverageIgnore - */ - public function __construct() - { - if ('testing' === config('app.env')) { - Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); - } - } - - - /** - * Transform the import job. - * - * @param ImportJob $importJob - * - * @return array - */ - public function transform(ImportJob $importJob): array - { - $tag = $importJob->tag; - $tagId = null; - $tagTag = null; - if (null !== $tag) { - $tagId = $tag->id; - $tagTag = $tag->tag; - } - $data = [ - 'id' => (int)$importJob->id, - 'created_at' => $importJob->created_at->toAtomString(), - 'updated_at' => $importJob->updated_at->toAtomString(), - 'tag_id' => $tagId, - 'tag_tag' => $tagTag, - 'key' => $importJob->key, - 'file_type' => $importJob->file_type, - 'provider' => $importJob->provider, - 'status' => $importJob->status, - 'stage' => $importJob->stage, - 'configuration' => json_encode($importJob->configuration), - 'extended_status' => json_encode($importJob->extended_status), - 'transactions' => json_encode($importJob->transactions), - 'errors' => json_encode($importJob->errors), - - 'links' => [ - [ - 'rel' => 'self', - 'uri' => '/import/' . $importJob->key, - ], - ], - ]; - - return $data; - } -} diff --git a/app/Transformers/ObjectGroupTransformer.php b/app/Transformers/ObjectGroupTransformer.php new file mode 100644 index 0000000000..c2f50a4216 --- /dev/null +++ b/app/Transformers/ObjectGroupTransformer.php @@ -0,0 +1,81 @@ +. + */ + +declare(strict_types=1); + +namespace FireflyIII\Transformers; + + +use Carbon\Carbon; +use FireflyIII\Models\Account; +use FireflyIII\Models\ObjectGroup; +use FireflyIII\Repositories\ObjectGroup\ObjectGroupRepositoryInterface; +use Log; + +/** + * Class AccountTransformer + */ +class ObjectGroupTransformer extends AbstractTransformer +{ + protected ObjectGroupRepositoryInterface $repository; + + /** + * + * AccountTransformer constructor. + * + * @codeCoverageIgnore + */ + public function __construct() + { + if ('testing' === config('app.env')) { + Log::warning(sprintf('%s should not be instantiated in the TEST environment!', get_class($this))); + } + + $this->repository = app(ObjectGroupRepositoryInterface::class); + } + + /** + * Transform the account. + * + * @param ObjectGroup $objectGroup + * + * @return array + */ + public function transform(ObjectGroup $objectGroup): array + { + $this->repository->setUser($objectGroup->user); + + return [ + 'id' => (int) $objectGroup->id, + 'created_at' => $objectGroup->created_at->toAtomString(), + 'updated_at' => $objectGroup->updated_at->toAtomString(), + 'title' => $objectGroup->title, + 'order' => $objectGroup->order, + 'links' => [ + [ + 'rel' => 'self', + 'uri' => '/groups/' . $objectGroup->id, + ], + ], + ]; + } + +} diff --git a/app/Transformers/PiggyBankTransformer.php b/app/Transformers/PiggyBankTransformer.php index 15aa4f6fe6..098a54d18a 100644 --- a/app/Transformers/PiggyBankTransformer.php +++ b/app/Transformers/PiggyBankTransformer.php @@ -25,6 +25,7 @@ namespace FireflyIII\Transformers; use FireflyIII\Models\Account; +use FireflyIII\Models\ObjectGroup; use FireflyIII\Models\PiggyBank; use FireflyIII\Repositories\Account\AccountRepositoryInterface; use FireflyIII\Repositories\Currency\CurrencyRepositoryInterface; @@ -83,6 +84,17 @@ class PiggyBankTransformer extends AbstractTransformer $notes = $this->piggyRepos->getNoteText($piggyBank); $notes = '' === $notes ? null : $notes; + $objectGroupId = null; + $objectGroupOrder = null; + $objectGroupTitle = null; + /** @var ObjectGroup $objectGroup */ + $objectGroup = $piggyBank->objectGroups->first(); + if (null !== $objectGroup) { + $objectGroupId = (int) $objectGroup->id; + $objectGroupOrder = (int) $objectGroup->order; + $objectGroupTitle = $objectGroup->title; + } + // get currently saved amount: $currentAmountStr = $this->piggyRepos->getCurrentAmount($piggyBank); $currentAmount = round($currentAmountStr, $currency->decimal_places); @@ -114,9 +126,12 @@ class PiggyBankTransformer extends AbstractTransformer 'save_per_month' => round($this->piggyRepos->getSuggestedMonthlyAmount($piggyBank), $currency->decimal_places), 'start_date' => $startDate, 'target_date' => $targetDate, - 'order' => (int)$piggyBank->order, + 'order' => (int) $piggyBank->order, 'active' => true, 'notes' => $notes, + 'object_group_id' => $objectGroupId, + 'object_group_order' => $objectGroupOrder, + 'object_group_title' => $objectGroupTitle, 'links' => [ [ 'rel' => 'self', diff --git a/app/User.php b/app/User.php index 53f1cdf805..e5ee944f4f 100644 --- a/app/User.php +++ b/app/User.php @@ -34,7 +34,7 @@ use FireflyIII\Models\Bill; use FireflyIII\Models\Budget; use FireflyIII\Models\Category; use FireflyIII\Models\CurrencyExchangeRate; -use FireflyIII\Models\ImportJob; +use FireflyIII\Models\ObjectGroup; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Preference; use FireflyIII\Models\Recurrence; @@ -45,6 +45,7 @@ use FireflyIII\Models\Tag; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionGroup; use FireflyIII\Models\TransactionJournal; +use Illuminate\Auth\Passwords\CanResetPassword; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsToMany; use Illuminate\Database\Eloquent\Relations\HasMany; @@ -89,7 +90,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read \Illuminate\Database\Eloquent\Collection|Category[] $categories * @property-read \Illuminate\Database\Eloquent\Collection|Client[] $clients * @property-read \Illuminate\Database\Eloquent\Collection|CurrencyExchangeRate[] $currencyExchangeRates - * @property-read \Illuminate\Database\Eloquent\Collection|ImportJob[] $importJobs * @property-read DatabaseNotificationCollection|DatabaseNotification[] $notifications * @property-read \Illuminate\Database\Eloquent\Collection|PiggyBank[] $piggyBanks * @property-read \Illuminate\Database\Eloquent\Collection|Preference[] $preferences @@ -123,7 +123,6 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read int|null $categories_count * @property-read int|null $clients_count * @property-read int|null $currency_exchange_rates_count - * @property-read int|null $import_jobs_count * @property-read int|null $notifications_count * @property-read int|null $piggy_banks_count * @property-read int|null $preferences_count @@ -138,6 +137,8 @@ use Symfony\Component\HttpKernel\Exception\NotFoundHttpException; * @property-read int|null $transactions_count * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\User whereMfaSecret($value) * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\User whereObjectguid($value) + * @property string|null $provider + * @method static \Illuminate\Database\Eloquent\Builder|\FireflyIII\User whereProvider($value) */ class User extends Authenticatable { @@ -256,6 +257,17 @@ class User extends Authenticatable return $this->hasMany(Budget::class); } + /** + * @codeCoverageIgnore + * Link to object groups. + * + * @return HasMany + */ + public function objectGroups(): HasMany + { + return $this->hasMany(ObjectGroup::class); + } + /** * @codeCoverageIgnore * Link to categories @@ -292,17 +304,6 @@ class User extends Authenticatable return bin2hex($bytes); } - /** - * @codeCoverageIgnore - * Link to import jobs. - * - * @return HasMany - */ - public function importJobs(): HasMany - { - return $this->hasMany(ImportJob::class); - } - /** * @codeCoverageIgnore * Link to piggy banks. diff --git a/app/Validation/FireflyValidator.php b/app/Validation/FireflyValidator.php index 208a6c87f8..8c10713282 100644 --- a/app/Validation/FireflyValidator.php +++ b/app/Validation/FireflyValidator.php @@ -505,6 +505,30 @@ class FireflyValidator extends Validator * * @return bool */ + public function validateUniqueObjectGroup($attribute, $value, $parameters): bool + { + $exclude = $parameters[0] ?? null; + $query = DB::table('object_groups') + ->whereNull('object_groups.deleted_at') + ->where('object_groups.user_id', auth()->user()->id) + ->where('object_groups.title', $value); + if (null !== $exclude) { + $query->where('object_groups.id', '!=', (int) $exclude); + } + + return 0 === $query->count(); + } + + + /** + * @param $attribute + * @param $value + * @param $parameters + * + * TODO this method does not need a for loop + * + * @return bool + */ public function validateUniquePiggyBankForUser($attribute, $value, $parameters): bool { $exclude = $parameters[0] ?? null; diff --git a/changelog.md b/changelog.md index f622e9ab46..c5cc3d291f 100644 --- a/changelog.md +++ b/changelog.md @@ -2,6 +2,45 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +## [5.3.0 (API 1.2.0) - 2020-08-01 + +Several alpha and beta releases preceded this release. + +- 5.3.0-alpha.1 on 2020-06-22 + +### Added +- Piggy banks can be divided over groups. Groups can be sorted on a separate page. This may prove to be useful to organize piggy banks. The feature will + expand to other objects in the future. +- [Issue 3392](https://github.com/firefly-iii/firefly-iii/issues/3392) Notes will be included in the export. +- [Issue 3184](https://github.com/firefly-iii/firefly-iii/issues/3184) You can now use the `REMOTE_USER` field to authenticate. Read [the documentation](https://docs.firefly-iii.org/advanced-installation/authentication#remote-user) carefully. +- [Issue 3403](https://github.com/firefly-iii/firefly-iii/issues/3403) More triggers have been added that respond to the date of a transaction. Read [the documentation](https://docs.firefly-iii.org/advanced-concepts/rules) +- You can now add an attachments to recurring transactions. + +### Changed +- Firefly III now requires **PHP 7.4** +- The Docker image is running on **port 8080** +- Firefly III has been upgraded to Laravel 7. +- [Issue 3455](https://github.com/firefly-iii/firefly-iii/issues/3455) Translations for the debug page. +- [Issue 3461](https://github.com/firefly-iii/firefly-iii/issues/3461) Inactive rules are no longer applied. + +### Removed +- All import routines have been removed. Use the separate importers. Read [the documentation](https://docs.firefly-iii.org/importing-data/introduction). + +### Fixed +- [Issue 3450](https://github.com/firefly-iii/firefly-iii/issues/3450) Missing translations. +- [Issue 3454](https://github.com/firefly-iii/firefly-iii/issues/3454) Fixed translations. +- [Issue 3437](https://github.com/firefly-iii/firefly-iii/issues/3437) Better "days left" counter. +- Fixed bad UUID generation. +- Fixed a null pointer in session date. + +### API +- New API for object groups. +- Expanded API for piggy banks to support object groups. + +### Known issues +- You may run into date conversion problems if you're living on the right side of GMT. If transactions appear a day early, let me know. + ## [5.2.8 (API 1.1.0)] - 2020-06-02 ### Fixed diff --git a/composer.json b/composer.json index ad4c983402..ed65b7ee94 100644 --- a/composer.json +++ b/composer.json @@ -69,7 +69,7 @@ } ], "require": { - "php": ">=7.3.0", + "php": ">=7.4.0", "ext-bcmath": "*", "ext-curl": "*", "ext-fileinfo": "*", @@ -84,16 +84,16 @@ "ext-xml": "*", "adldap2/adldap2-laravel": "6.*", "bacon/bacon-qr-code": "1.*", - "bunq/sdk_php": "dev-master", "davejamesmiller/laravel-breadcrumbs": "5.*", "doctrine/dbal": "2.*", "fideloper/proxy": "4.*", "jc5/google2fa-laravel": "2.0.4", - "laravel/framework": "^6.0", + "laravel/framework": "^7.0", "laravel/passport": "8.*", + "laravel/ui": "^2.0", "laravelcollective/html": "6.*", "league/commonmark": "1.*", - "league/csv": "9.*", + "league/csv": "^9.6", "league/fractal": "0.*", "pragmarx/google2fa": "^7.0", "pragmarx/recovery": "^0.1.0", @@ -107,7 +107,7 @@ "fzaninotto/faker": "1.*", "johnkary/phpunit-speedtrap": "^3.1", "mockery/mockery": "1.*", - "phpunit/phpunit": "8.*", + "phpunit/phpunit": "^8.5", "psalm/plugin-laravel": "^1.1", "roave/security-advisories": "dev-master", "vimeo/psalm": "^3.10" diff --git a/composer.lock b/composer.lock index 8d882affdb..86861b71b8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5af5d9774ef0e82cd34d08c63020e85d", + "content-hash": "ff245cbb0236e439d420e96a58327852", "packages": [ { "name": "adldap2/adldap2", @@ -165,70 +165,6 @@ "homepage": "https://github.com/Bacon/BaconQrCode", "time": "2017-10-17T09:59:25+00:00" }, - { - "name": "bunq/sdk_php", - "version": "dev-master", - "source": { - "type": "git", - "url": "https://github.com/bunq/sdk_php.git", - "reference": "d97d2a710038d183b711825864584e2d31e30e35" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/bunq/sdk_php/zipball/d97d2a710038d183b711825864584e2d31e30e35", - "reference": "d97d2a710038d183b711825864584e2d31e30e35", - "shasum": "" - }, - "require": { - "ext-curl": "*", - "ext-json": "*", - "ext-mbstring": "*", - "guzzlehttp/guzzle": "~6", - "php": "^7.0.13" - }, - "require-dev": { - "brianium/paratest": "^1.1", - "friendsofphp/php-cs-fixer": "^2.4", - "jakub-onderka/php-parallel-lint": "^0.9.2", - "phpro/grumphp": "^0.11.6", - "phpstan/phpstan": "^0.8", - "phpunit/phpunit": "^6.0.13", - "sebastian/phpcpd": "^3.0", - "sensiolabs/security-checker": "^5.0" - }, - "bin": [ - "bin/bunq-install" - ], - "type": "library", - "autoload": { - "psr-4": { - "bunq\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "bunq", - "email": "sdk@bunq.com", - "homepage": "https://www.bunq.com", - "role": "Owner" - } - ], - "description": "bunq PHP SDK", - "homepage": "https://bunq.com/", - "keywords": [ - "api", - "bunq", - "finance", - "open-banking", - "payment", - "sepa" - ], - "time": "2020-04-03T15:48:46+00:00" - }, { "name": "davejamesmiller/laravel-breadcrumbs", "version": "5.3.2", @@ -540,6 +476,20 @@ "sqlserver", "sqlsrv" ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fdbal", + "type": "tidelift" + } + ], "time": "2020-04-20T17:19:26+00:00" }, { @@ -841,16 +791,16 @@ }, { "name": "egulias/email-validator", - "version": "2.1.17", + "version": "2.1.18", "source": { "type": "git", "url": "https://github.com/egulias/EmailValidator.git", - "reference": "ade6887fd9bd74177769645ab5c474824f8a418a" + "reference": "cfa3d44471c7f5bfb684ac2b0da7114283d78441" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/ade6887fd9bd74177769645ab5c474824f8a418a", - "reference": "ade6887fd9bd74177769645ab5c474824f8a418a", + "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/cfa3d44471c7f5bfb684ac2b0da7114283d78441", + "reference": "cfa3d44471c7f5bfb684ac2b0da7114283d78441", "shasum": "" }, "require": { @@ -874,7 +824,7 @@ }, "autoload": { "psr-4": { - "Egulias\\EmailValidator\\": "EmailValidator" + "Egulias\\EmailValidator\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -895,7 +845,7 @@ "validation", "validator" ], - "time": "2020-02-13T22:36:52+00:00" + "time": "2020-06-16T20:11:17+00:00" }, { "name": "facade/ignition-contracts", @@ -1047,16 +997,16 @@ }, { "name": "guzzlehttp/guzzle", - "version": "6.5.4", + "version": "6.5.5", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d" + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/a4a1b6930528a8f7ee03518e6442ec7a44155d9d", - "reference": "a4a1b6930528a8f7ee03518e6442ec7a44155d9d", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", + "reference": "9d4290de1cfd701f38099ef7e183b64b4b7b0c5e", "shasum": "" }, "require": { @@ -1064,7 +1014,7 @@ "guzzlehttp/promises": "^1.0", "guzzlehttp/psr7": "^1.6.1", "php": ">=5.5", - "symfony/polyfill-intl-idn": "1.17.0" + "symfony/polyfill-intl-idn": "^1.17.0" }, "require-dev": { "ext-curl": "*", @@ -1110,7 +1060,7 @@ "rest", "web service" ], - "time": "2020-05-25T19:35:05+00:00" + "time": "2020-06-16T21:01:06+00:00" }, { "name": "guzzlehttp/promises", @@ -1464,16 +1414,16 @@ }, { "name": "laravel/framework", - "version": "v6.18.18", + "version": "v7.16.1", "source": { "type": "git", "url": "https://github.com/laravel/framework.git", - "reference": "9e5226ecc28f960cba1bd38b6d1d82a52e072dc3" + "reference": "dc9cd8338d222dec2d9962553639e08c4585fa5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/framework/zipball/9e5226ecc28f960cba1bd38b6d1d82a52e072dc3", - "reference": "9e5226ecc28f960cba1bd38b6d1d82a52e072dc3", + "url": "https://api.github.com/repos/laravel/framework/zipball/dc9cd8338d222dec2d9962553639e08c4585fa5b", + "reference": "dc9cd8338d222dec2d9962553639e08c4585fa5b", "shasum": "" }, "require": { @@ -1485,29 +1435,34 @@ "ext-openssl": "*", "league/commonmark": "^1.3", "league/flysystem": "^1.0.34", - "monolog/monolog": "^1.12|^2.0", - "nesbot/carbon": "^2.0", + "monolog/monolog": "^2.0", + "nesbot/carbon": "^2.17", "opis/closure": "^3.1", - "php": "^7.2", + "php": "^7.2.5", "psr/container": "^1.0", "psr/simple-cache": "^1.0", - "ramsey/uuid": "^3.7", + "ramsey/uuid": "^3.7|^4.0", "swiftmailer/swiftmailer": "^6.0", - "symfony/console": "^4.3.4", - "symfony/debug": "^4.3.4", - "symfony/finder": "^4.3.4", - "symfony/http-foundation": "^4.3.4", - "symfony/http-kernel": "^4.3.4", + "symfony/console": "^5.0", + "symfony/error-handler": "^5.0", + "symfony/finder": "^5.0", + "symfony/http-foundation": "^5.0", + "symfony/http-kernel": "^5.0", + "symfony/mime": "^5.0", "symfony/polyfill-php73": "^1.17", - "symfony/process": "^4.3.4", - "symfony/routing": "^4.3.4", - "symfony/var-dumper": "^4.3.4", - "tijsverkoyen/css-to-inline-styles": "^2.2.1", - "vlucas/phpdotenv": "^3.3" + "symfony/process": "^5.0", + "symfony/routing": "^5.0", + "symfony/var-dumper": "^5.0", + "tijsverkoyen/css-to-inline-styles": "^2.2.2", + "vlucas/phpdotenv": "^4.0", + "voku/portable-ascii": "^1.4.8" }, "conflict": { "tightenco/collect": "<5.5.33" }, + "provide": { + "psr/container-implementation": "1.0" + }, "replace": { "illuminate/auth": "self.version", "illuminate/broadcasting": "self.version", @@ -1534,6 +1489,7 @@ "illuminate/routing": "self.version", "illuminate/session": "self.version", "illuminate/support": "self.version", + "illuminate/testing": "self.version", "illuminate/translation": "self.version", "illuminate/validation": "self.version", "illuminate/view": "self.version" @@ -1542,19 +1498,20 @@ "aws/aws-sdk-php": "^3.0", "doctrine/dbal": "^2.6", "filp/whoops": "^2.4", - "guzzlehttp/guzzle": "^6.3|^7.0", + "guzzlehttp/guzzle": "^6.3.1|^7.0", "league/flysystem-cached-adapter": "^1.0", "mockery/mockery": "^1.3.1", "moontoast/math": "^1.1", - "orchestra/testbench-core": "^4.0", + "orchestra/testbench-core": "^5.0", "pda/pheanstalk": "^4.0", - "phpunit/phpunit": "^7.5.15|^8.4|^9.0", + "phpunit/phpunit": "^8.4|^9.0", "predis/predis": "^1.1.1", - "symfony/cache": "^4.3.4" + "symfony/cache": "^5.0" }, "suggest": { "aws/aws-sdk-php": "Required to use the SQS queue driver, DynamoDb failed job storage and SES mail driver (^3.0).", "doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).", + "ext-ftp": "Required to use the Flysystem FTP driver.", "ext-gd": "Required to use Illuminate\\Http\\Testing\\FileFactory::image().", "ext-memcached": "Required to use the memcache cache driver.", "ext-pcntl": "Required to use all features of the queue worker.", @@ -1562,24 +1519,27 @@ "ext-redis": "Required to use the Redis cache and queue drivers (^4.0|^5.0).", "filp/whoops": "Required for friendly error pages in development (^2.4).", "fzaninotto/faker": "Required to use the eloquent factory builder (^1.9.1).", - "guzzlehttp/guzzle": "Required to use the Mailgun mail driver and the ping methods on schedules (^6.0|^7.0).", + "guzzlehttp/guzzle": "Required to use the HTTP Client, Mailgun mail driver and the ping methods on schedules (^6.3.1|^7.0).", "laravel/tinker": "Required to use the tinker console command (^2.0).", "league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).", "league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).", "league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).", + "mockery/mockery": "Required to use mocking (^1.3.1).", "moontoast/math": "Required to use ordered UUIDs (^1.1).", "nyholm/psr7": "Required to use PSR-7 bridging features (^1.2).", "pda/pheanstalk": "Required to use the beanstalk queue driver (^4.0).", + "phpunit/phpunit": "Required to use assertions and run tests (^8.4|^9.0).", "psr/http-message": "Required to allow Storage::put to accept a StreamInterface (^1.0).", "pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^4.0).", - "symfony/cache": "Required to PSR-6 cache bridge (^4.3.4).", - "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^1.2).", + "symfony/cache": "Required to PSR-6 cache bridge (^5.0).", + "symfony/filesystem": "Required to create relative storage directory symbolic links (^5.0).", + "symfony/psr-http-message-bridge": "Required to use PSR-7 bridging features (^2.0).", "wildbit/swiftmailer-postmark": "Required to use Postmark mail driver (^3.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.x-dev" + "dev-master": "7.x-dev" } }, "autoload": { @@ -1607,7 +1567,7 @@ "framework", "laravel" ], - "time": "2020-06-02T22:32:07+00:00" + "time": "2020-06-16T14:31:25+00:00" }, { "name": "laravel/passport", @@ -1682,6 +1642,61 @@ ], "time": "2020-05-05T14:25:53+00:00" }, + { + "name": "laravel/ui", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/laravel/ui.git", + "reference": "15368c5328efb7ce94f35ca750acde9b496ab1b1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/ui/zipball/15368c5328efb7ce94f35ca750acde9b496ab1b1", + "reference": "15368c5328efb7ce94f35ca750acde9b496ab1b1", + "shasum": "" + }, + "require": { + "illuminate/console": "^7.0", + "illuminate/filesystem": "^7.0", + "illuminate/support": "^7.0", + "php": "^7.2.5" + }, + "require-dev": { + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^8.0" + }, + "type": "library", + "extra": { + "laravel": { + "providers": [ + "Laravel\\Ui\\UiServiceProvider" + ] + } + }, + "autoload": { + "psr-4": { + "Laravel\\Ui\\": "src/", + "Illuminate\\Foundation\\Auth\\": "auth-backend/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + } + ], + "description": "Laravel UI utilities and presets.", + "keywords": [ + "laravel", + "ui" + ], + "time": "2020-04-29T15:06:45+00:00" + }, { "name": "laravelcollective/html", "version": "v6.1.2", @@ -1817,21 +1832,21 @@ }, { "name": "league/commonmark", - "version": "1.4.3", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/commonmark.git", - "reference": "412639f7cfbc0b31ad2455b2fe965095f66ae505" + "reference": "fc33ca12575e98e57cdce7d5f38b2ca5335714b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/412639f7cfbc0b31ad2455b2fe965095f66ae505", - "reference": "412639f7cfbc0b31ad2455b2fe965095f66ae505", + "url": "https://api.github.com/repos/thephpleague/commonmark/zipball/fc33ca12575e98e57cdce7d5f38b2ca5335714b3", + "reference": "fc33ca12575e98e57cdce7d5f38b2ca5335714b3", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": "^7.1" + "php": "^7.1 || ^8.0" }, "conflict": { "scrutinizer/ocular": "1.7.*" @@ -1853,11 +1868,6 @@ "bin/commonmark" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, "autoload": { "psr-4": { "League\\CommonMark\\": "src" @@ -1913,7 +1923,7 @@ "type": "tidelift" } ], - "time": "2020-05-04T22:15:21+00:00" + "time": "2020-06-21T20:50:13+00:00" }, { "name": "league/csv", @@ -1984,6 +1994,12 @@ "transform", "write" ], + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], "time": "2020-03-17T15:15:35+00:00" }, { @@ -2522,16 +2538,16 @@ }, { "name": "opis/closure", - "version": "3.5.3", + "version": "3.5.5", "source": { "type": "git", "url": "https://github.com/opis/closure.git", - "reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca" + "reference": "dec9fc5ecfca93f45cd6121f8e6f14457dff372c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/opis/closure/zipball/cac47092144043d5d676e2e7cf8d0d2f83fc89ca", - "reference": "cac47092144043d5d676e2e7cf8d0d2f83fc89ca", + "url": "https://api.github.com/repos/opis/closure/zipball/dec9fc5ecfca93f45cd6121f8e6f14457dff372c", + "reference": "dec9fc5ecfca93f45cd6121f8e6f14457dff372c", "shasum": "" }, "require": { @@ -2579,7 +2595,7 @@ "serialization", "serialize" ], - "time": "2020-05-25T09:32:45+00:00" + "time": "2020-06-17T14:59:55+00:00" }, { "name": "paragonie/constant_time_encoding", @@ -2740,16 +2756,16 @@ }, { "name": "phpoption/phpoption", - "version": "1.7.3", + "version": "1.7.4", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "4acfd6a4b33a509d8c88f50e5222f734b6aeebae" + "reference": "b2ada2ad5d8a32b89088b8adc31ecd2e3a13baf3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/4acfd6a4b33a509d8c88f50e5222f734b6aeebae", - "reference": "4acfd6a4b33a509d8c88f50e5222f734b6aeebae", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/b2ada2ad5d8a32b89088b8adc31ecd2e3a13baf3", + "reference": "b2ada2ad5d8a32b89088b8adc31ecd2e3a13baf3", "shasum": "" }, "require": { @@ -2791,7 +2807,17 @@ "php", "type" ], - "time": "2020-03-21T18:07:53+00:00" + "funding": [ + { + "url": "https://github.com/GrahamCampbell", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpoption/phpoption", + "type": "tidelift" + } + ], + "time": "2020-06-07T10:40:07+00:00" }, { "name": "phpseclib/phpseclib", @@ -2883,6 +2909,20 @@ "x.509", "x509" ], + "funding": [ + { + "url": "https://github.com/terrafrost", + "type": "github" + }, + { + "url": "https://www.patreon.com/phpseclib", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpseclib/phpseclib", + "type": "tidelift" + } + ], "time": "2020-04-04T23:17:33+00:00" }, { @@ -3225,6 +3265,52 @@ ], "time": "2017-02-14T16:28:37+00:00" }, + { + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "time": "2019-01-08T18:20:26+00:00" + }, { "name": "psr/http-factory", "version": "1.0.1", @@ -3685,42 +3771,44 @@ }, { "name": "symfony/console", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "326b064d804043005526f5a0494cfb49edb59bb0" + "reference": "34ac555a3627e324b660e318daa07572e1140123" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/326b064d804043005526f5a0494cfb49edb59bb0", - "reference": "326b064d804043005526f5a0494cfb49edb59bb0", + "url": "https://api.github.com/repos/symfony/console/zipball/34ac555a3627e324b660e318daa07572e1140123", + "reference": "34ac555a3627e324b660e318daa07572e1140123", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2" + "symfony/service-contracts": "^1.1|^2", + "symfony/string": "^5.1" }, "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/event-dispatcher": "<4.3|>=5", + "symfony/dependency-injection": "<4.4", + "symfony/dotenv": "<5.1", + "symfony/event-dispatcher": "<4.4", "symfony/lock": "<4.4", - "symfony/process": "<3.3" + "symfony/process": "<4.4" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/event-dispatcher": "^4.3", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/event-dispatcher": "^4.4|^5.0", "symfony/lock": "^4.4|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/var-dumper": "^4.3|^5.0" + "symfony/process": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0" }, "suggest": { "psr/log": "For using the console logger", @@ -3731,7 +3819,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -3772,11 +3860,11 @@ "type": "tidelift" } ], - "time": "2020-05-30T20:06:45+00:00" + "time": "2020-06-15T12:59:21+00:00" }, { "name": "symfony/css-selector", - "version": "v5.1.0", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", @@ -3842,42 +3930,31 @@ "time": "2020-05-20T17:43:50+00:00" }, { - "name": "symfony/debug", - "version": "v4.4.9", + "name": "symfony/deprecation-contracts", + "version": "v2.1.2", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/28f92d08bb6d1fddf8158e02c194ad43870007e6", - "reference": "28f92d08bb6d1fddf8158e02c194ad43870007e6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", + "reference": "dd99cb3a0aff6cadd2a8d7d7ed72c2161e218337", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/polyfill-php80": "^1.15" - }, - "conflict": { - "symfony/http-kernel": "<3.4" - }, - "require-dev": { - "symfony/http-kernel": "^3.4|^4.0|^5.0" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "2.1-dev" } }, "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "function.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -3886,15 +3963,15 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "funding": [ { @@ -3910,37 +3987,37 @@ "type": "tidelift" } ], - "time": "2020-05-24T08:33:35+00:00" + "time": "2020-05-27T08:34:37+00:00" }, { "name": "symfony/error-handler", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "0df9a23c0f9eddbb6682479fee6fd58b88add75b" + "reference": "7d0b927b9d3dc41d7d46cda38cbfcd20cdcbb896" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/0df9a23c0f9eddbb6682479fee6fd58b88add75b", - "reference": "0df9a23c0f9eddbb6682479fee6fd58b88add75b", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/7d0b927b9d3dc41d7d46cda38cbfcd20cdcbb896", + "reference": "7d0b927b9d3dc41d7d46cda38cbfcd20cdcbb896", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "~1.0", - "symfony/debug": "^4.4.5", + "php": ">=7.2.5", + "psr/log": "^1.0", "symfony/polyfill-php80": "^1.15", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { + "symfony/deprecation-contracts": "^2.1", "symfony/http-kernel": "^4.4|^5.0", "symfony/serializer": "^4.4|^5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -3981,41 +4058,43 @@ "type": "tidelift" } ], - "time": "2020-05-28T10:39:14+00:00" + "time": "2020-05-30T20:35:19+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a5370aaa7807c7a439b21386661ffccf3dff2866" + "reference": "cc0d059e2e997e79ca34125a52f3e33de4424ac7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a5370aaa7807c7a439b21386661ffccf3dff2866", - "reference": "a5370aaa7807c7a439b21386661ffccf3dff2866", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/cc0d059e2e997e79ca34125a52f3e33de4424ac7", + "reference": "cc0d059e2e997e79ca34125a52f3e33de4424ac7", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/event-dispatcher-contracts": "^1.1" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/event-dispatcher-contracts": "^2", + "symfony/polyfill-php80": "^1.15" }, "conflict": { - "symfony/dependency-injection": "<3.4" + "symfony/dependency-injection": "<4.4" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "1.1" + "symfony/event-dispatcher-implementation": "2.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", + "symfony/config": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^3.4|^4.0|^5.0" + "symfony/stopwatch": "^4.4|^5.0" }, "suggest": { "symfony/dependency-injection": "", @@ -4024,7 +4103,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -4065,33 +4144,33 @@ "type": "tidelift" } ], - "time": "2020-05-20T08:37:50+00:00" + "time": "2020-05-20T17:43:50+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v1.1.7", + "version": "v2.1.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18" + "reference": "405952c4e90941a17e52ef7489a2bd94870bb290" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c43ab685673fb6c8d84220c77897b1d6cdbe1d18", - "reference": "c43ab685673fb6c8d84220c77897b1d6cdbe1d18", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/405952c4e90941a17e52ef7489a2bd94870bb290", + "reference": "405952c4e90941a17e52ef7489a2bd94870bb290", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.2.5", + "psr/event-dispatcher": "^1" }, "suggest": { - "psr/event-dispatcher": "", "symfony/event-dispatcher-implementation": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -4123,29 +4202,43 @@ "interoperability", "standards" ], - "time": "2019-09-17T09:54:03+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-05-20T17:43:50+00:00" }, { "name": "symfony/finder", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "5729f943f9854c5781984ed4907bbb817735776b" + "reference": "4298870062bfc667cb78d2b379be4bf5dec5f187" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/5729f943f9854c5781984ed4907bbb817735776b", - "reference": "5729f943f9854c5781984ed4907bbb817735776b", + "url": "https://api.github.com/repos/symfony/finder/zipball/4298870062bfc667cb78d2b379be4bf5dec5f187", + "reference": "4298870062bfc667cb78d2b379be4bf5dec5f187", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.2.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -4186,35 +4279,41 @@ "type": "tidelift" } ], - "time": "2020-03-27T16:54:36+00:00" + "time": "2020-05-20T17:43:50+00:00" }, { "name": "symfony/http-foundation", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "3adfbd7098c850b02d107330b7b9deacf2581578" + "reference": "f93055171b847915225bd5b0a5792888419d8d75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/3adfbd7098c850b02d107330b7b9deacf2581578", - "reference": "3adfbd7098c850b02d107330b7b9deacf2581578", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f93055171b847915225bd5b0a5792888419d8d75", + "reference": "f93055171b847915225bd5b0a5792888419d8d75", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/mime": "^4.3|^5.0", - "symfony/polyfill-mbstring": "~1.1" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php80": "^1.15" }, "require-dev": { "predis/predis": "~1.0", - "symfony/expression-language": "^3.4|^4.0|^5.0" + "symfony/cache": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/mime": "^4.4|^5.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -4255,60 +4354,68 @@ "type": "tidelift" } ], - "time": "2020-05-23T09:11:46+00:00" + "time": "2020-06-15T06:52:54+00:00" }, { "name": "symfony/http-kernel", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467" + "reference": "a18c27ace1ef344ffcb129a5b089bad7643b387a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/54526b598d7fc86a67850488b194a88a79ab8467", - "reference": "54526b598d7fc86a67850488b194a88a79ab8467", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/a18c27ace1ef344ffcb129a5b089bad7643b387a", + "reference": "a18c27ace1ef344ffcb129a5b089bad7643b387a", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "psr/log": "~1.0", - "symfony/error-handler": "^4.4", - "symfony/event-dispatcher": "^4.4", + "symfony/deprecation-contracts": "^2.1", + "symfony/error-handler": "^4.4|^5.0", + "symfony/event-dispatcher": "^5.0", "symfony/http-foundation": "^4.4|^5.0", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.15" }, "conflict": { - "symfony/browser-kit": "<4.3", - "symfony/config": "<3.4", - "symfony/console": ">=5", - "symfony/dependency-injection": "<4.3", - "symfony/translation": "<4.2", - "twig/twig": "<1.34|<2.4,>=2" + "symfony/browser-kit": "<4.4", + "symfony/cache": "<5.0", + "symfony/config": "<5.0", + "symfony/console": "<4.4", + "symfony/dependency-injection": "<4.4", + "symfony/doctrine-bridge": "<5.0", + "symfony/form": "<5.0", + "symfony/http-client": "<5.0", + "symfony/mailer": "<5.0", + "symfony/messenger": "<5.0", + "symfony/translation": "<5.0", + "symfony/twig-bridge": "<5.0", + "symfony/validator": "<5.0", + "twig/twig": "<2.4" }, "provide": { "psr/log-implementation": "1.0" }, "require-dev": { "psr/cache": "~1.0", - "symfony/browser-kit": "^4.3|^5.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0", - "symfony/css-selector": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^4.3|^5.0", - "symfony/dom-crawler": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/finder": "^3.4|^4.0|^5.0", - "symfony/process": "^3.4|^4.0|^5.0", - "symfony/routing": "^3.4|^4.0|^5.0", - "symfony/stopwatch": "^3.4|^4.0|^5.0", - "symfony/templating": "^3.4|^4.0|^5.0", - "symfony/translation": "^4.2|^5.0", + "symfony/browser-kit": "^4.4|^5.0", + "symfony/config": "^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/css-selector": "^4.4|^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/dom-crawler": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/process": "^4.4|^5.0", + "symfony/routing": "^4.4|^5.0", + "symfony/stopwatch": "^4.4|^5.0", + "symfony/translation": "^4.4|^5.0", "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^1.34|^2.4|^3.0" + "twig/twig": "^2.4|^3.0" }, "suggest": { "symfony/browser-kit": "", @@ -4319,7 +4426,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -4360,20 +4467,20 @@ "type": "tidelift" } ], - "time": "2020-05-31T05:25:51+00:00" + "time": "2020-06-15T13:51:38+00:00" }, { "name": "symfony/mime", - "version": "v5.1.0", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "56261f89385f9d13cf843a5101ac72131190bc91" + "reference": "c0c418f05e727606e85b482a8591519c4712cf45" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/56261f89385f9d13cf843a5101ac72131190bc91", - "reference": "56261f89385f9d13cf843a5101ac72131190bc91", + "url": "https://api.github.com/repos/symfony/mime/zipball/c0c418f05e727606e85b482a8591519c4712cf45", + "reference": "c0c418f05e727606e85b482a8591519c4712cf45", "shasum": "" }, "require": { @@ -4437,20 +4544,20 @@ "type": "tidelift" } ], - "time": "2020-05-25T12:33:44+00:00" + "time": "2020-06-09T15:07:35+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9" + "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/e94c8b1bbe2bc77507a1056cdb06451c75b427f9", - "reference": "e94c8b1bbe2bc77507a1056cdb06451c75b427f9", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d", + "reference": "2edd75b8b35d62fd3eeabba73b26b8f1f60ce13d", "shasum": "" }, "require": { @@ -4463,6 +4570,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4509,20 +4620,20 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:14:59+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { "name": "symfony/polyfill-iconv", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-iconv.git", - "reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424" + "reference": "ba6c9c18db36235b859cc29b8372d1c01298c035" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/c4de7601eefbf25f9d47190abe07f79fe0a27424", - "reference": "c4de7601eefbf25f9d47190abe07f79fe0a27424", + "url": "https://api.github.com/repos/symfony/polyfill-iconv/zipball/ba6c9c18db36235b859cc29b8372d1c01298c035", + "reference": "ba6c9c18db36235b859cc29b8372d1c01298c035", "shasum": "" }, "require": { @@ -4535,6 +4646,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4582,20 +4697,98 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:47:27+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { - "name": "symfony/polyfill-intl-idn", - "version": "v1.17.0", + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.17.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-intl-idn.git", - "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a" + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "6e4dbcf5e81eba86e36731f94fe56b1726835846" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/3bff59ea7047e925be6b7f2059d60af31bb46d6a", - "reference": "3bff59ea7047e925be6b7f2059d60af31bb46d6a", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/6e4dbcf5e81eba86e36731f94fe56b1726835846", + "reference": "6e4dbcf5e81eba86e36731f94fe56b1726835846", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-06-06T08:46:27+00:00" + }, + { + "name": "symfony/polyfill-intl-idn", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-idn.git", + "reference": "a57f8161502549a742a63c09f0a604997bf47027" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-idn/zipball/a57f8161502549a742a63c09f0a604997bf47027", + "reference": "a57f8161502549a742a63c09f0a604997bf47027", "shasum": "" }, "require": { @@ -4610,6 +4803,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4658,20 +4855,101 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:47:27+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "v1.17.0", + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.17.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "fa79b11539418b02fc5e1897267673ba2c19419c" + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "40309d1700e8f72447bb9e7b54af756eeea35620" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/fa79b11539418b02fc5e1897267673ba2c19419c", - "reference": "fa79b11539418b02fc5e1897267673ba2c19419c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/40309d1700e8f72447bb9e7b54af756eeea35620", + "reference": "40309d1700e8f72447bb9e7b54af756eeea35620", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-06-14T14:40:37+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.17.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "7110338d81ce1cbc3e273136e4574663627037a7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/7110338d81ce1cbc3e273136e4574663627037a7", + "reference": "7110338d81ce1cbc3e273136e4574663627037a7", "shasum": "" }, "require": { @@ -4684,6 +4962,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4731,20 +5013,20 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:47:27+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { "name": "symfony/polyfill-php56", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php56.git", - "reference": "e3c8c138280cdfe4b81488441555583aa1984e23" + "reference": "a25861bb3c79b0ec2da9ede51de2ea573818b943" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/e3c8c138280cdfe4b81488441555583aa1984e23", - "reference": "e3c8c138280cdfe4b81488441555583aa1984e23", + "url": "https://api.github.com/repos/symfony/polyfill-php56/zipball/a25861bb3c79b0ec2da9ede51de2ea573818b943", + "reference": "a25861bb3c79b0ec2da9ede51de2ea573818b943", "shasum": "" }, "require": { @@ -4755,6 +5037,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4801,7 +5087,7 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:47:27+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { "name": "symfony/polyfill-php72", @@ -4874,16 +5160,16 @@ }, { "name": "symfony/polyfill-php73", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc" + "reference": "fa0837fe02d617d31fbb25f990655861bb27bd1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a760d8964ff79ab9bf057613a5808284ec852ccc", - "reference": "a760d8964ff79ab9bf057613a5808284ec852ccc", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fa0837fe02d617d31fbb25f990655861bb27bd1a", + "reference": "fa0837fe02d617d31fbb25f990655861bb27bd1a", "shasum": "" }, "require": { @@ -4893,6 +5179,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -4942,20 +5232,20 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:47:27+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "5e30b2799bc1ad68f7feb62b60a73743589438dd" + "reference": "4a5b6bba3259902e386eb80dd1956181ee90b5b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/5e30b2799bc1ad68f7feb62b60a73743589438dd", - "reference": "5e30b2799bc1ad68f7feb62b60a73743589438dd", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/4a5b6bba3259902e386eb80dd1956181ee90b5b2", + "reference": "4a5b6bba3259902e386eb80dd1956181ee90b5b2", "shasum": "" }, "require": { @@ -4965,6 +5255,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -5018,20 +5312,20 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:47:27+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { "name": "symfony/polyfill-util", - "version": "v1.17.0", + "version": "v1.17.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-util.git", - "reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7" + "reference": "6dd644eda43cd2f3daa883d728d8ab4120a05af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/4afb4110fc037752cf0ce9869f9ab8162c4e20d7", - "reference": "4afb4110fc037752cf0ce9869f9ab8162c4e20d7", + "url": "https://api.github.com/repos/symfony/polyfill-util/zipball/6dd644eda43cd2f3daa883d728d8ab4120a05af6", + "reference": "6dd644eda43cd2f3daa883d728d8ab4120a05af6", "shasum": "" }, "require": { @@ -5041,6 +5335,10 @@ "extra": { "branch-alias": { "dev-master": "1.17-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { @@ -5084,29 +5382,30 @@ "type": "tidelift" } ], - "time": "2020-05-12T16:14:59+00:00" + "time": "2020-06-06T08:46:27+00:00" }, { "name": "symfony/process", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "c714958428a85c86ab97e3a0c96db4c4f381b7f5" + "reference": "7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/c714958428a85c86ab97e3a0c96db4c4f381b7f5", - "reference": "c714958428a85c86ab97e3a0c96db4c4f381b7f5", + "url": "https://api.github.com/repos/symfony/process/zipball/7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1", + "reference": "7f6378c1fa2147eeb1b4c385856ce9de0d46ebd1", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.15" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -5147,7 +5446,7 @@ "type": "tidelift" } ], - "time": "2020-05-30T20:06:45+00:00" + "time": "2020-05-30T20:35:19+00:00" }, { "name": "symfony/psr-http-message-bridge", @@ -5215,34 +5514,36 @@ }, { "name": "symfony/routing", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "0f557911dde75c2a9652b8097bd7c9f54507f646" + "reference": "bbd0ba121d623f66d165a55a108008968911f3eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/0f557911dde75c2a9652b8097bd7c9f54507f646", - "reference": "0f557911dde75c2a9652b8097bd7c9f54507f646", + "url": "https://api.github.com/repos/symfony/routing/zipball/bbd0ba121d623f66d165a55a108008968911f3eb", + "reference": "bbd0ba121d623f66d165a55a108008968911f3eb", "shasum": "" }, "require": { - "php": "^7.1.3" + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", + "symfony/polyfill-php80": "^1.15" }, "conflict": { - "symfony/config": "<4.2", - "symfony/dependency-injection": "<3.4", - "symfony/yaml": "<3.4" + "symfony/config": "<5.0", + "symfony/dependency-injection": "<4.4", + "symfony/yaml": "<4.4" }, "require-dev": { "doctrine/annotations": "~1.2", "psr/log": "~1.0", - "symfony/config": "^4.2|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/expression-language": "^3.4|^4.0|^5.0", - "symfony/http-foundation": "^3.4|^4.0|^5.0", - "symfony/yaml": "^3.4|^4.0|^5.0" + "symfony/config": "^5.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/expression-language": "^4.4|^5.0", + "symfony/http-foundation": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0" }, "suggest": { "doctrine/annotations": "For using the annotation loader", @@ -5254,7 +5555,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -5301,7 +5602,7 @@ "type": "tidelift" } ], - "time": "2020-05-30T20:07:26+00:00" + "time": "2020-06-10T11:49:58+00:00" }, { "name": "symfony/service-contracts", @@ -5376,43 +5677,130 @@ "time": "2020-05-20T17:43:50+00:00" }, { - "name": "symfony/translation", - "version": "v4.4.9", + "name": "symfony/string", + "version": "v5.1.2", "source": { "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "79d3ef9096a6a6047dbc69218b68c7b7f63193af" + "url": "https://github.com/symfony/string.git", + "reference": "ac70459db781108db7c6d8981dd31ce0e29e3298" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/79d3ef9096a6a6047dbc69218b68c7b7f63193af", - "reference": "79d3ef9096a6a6047dbc69218b68c7b7f63193af", + "url": "https://api.github.com/repos/symfony/string/zipball/ac70459db781108db7c6d8981dd31ce0e29e3298", + "reference": "ac70459db781108db7c6d8981dd31ce0e29e3298", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^1.1.6|^2" + "symfony/polyfill-php80": "~1.15" + }, + "require-dev": { + "symfony/error-handler": "^4.4|^5.0", + "symfony/http-client": "^4.4|^5.0", + "symfony/translation-contracts": "^1.1|^2", + "symfony/var-exporter": "^4.4|^5.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "files": [ + "Resources/functions.php" + ], + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony String component", + "homepage": "https://symfony.com", + "keywords": [ + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" + ], + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-06-11T12:16:36+00:00" + }, + { + "name": "symfony/translation", + "version": "v5.1.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/translation.git", + "reference": "d387f07d4c15f9c09439cf3f13ddbe0b2c5e8be2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/translation/zipball/d387f07d4c15f9c09439cf3f13ddbe0b2c5e8be2", + "reference": "d387f07d4c15f9c09439cf3f13ddbe0b2c5e8be2", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php80": "^1.15", + "symfony/translation-contracts": "^2" }, "conflict": { - "symfony/config": "<3.4", - "symfony/dependency-injection": "<3.4", - "symfony/http-kernel": "<4.4", - "symfony/yaml": "<3.4" + "symfony/config": "<4.4", + "symfony/dependency-injection": "<5.0", + "symfony/http-kernel": "<5.0", + "symfony/twig-bundle": "<5.0", + "symfony/yaml": "<4.4" }, "provide": { - "symfony/translation-implementation": "1.0" + "symfony/translation-implementation": "2.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "^3.4|^4.0|^5.0", - "symfony/console": "^3.4|^4.0|^5.0", - "symfony/dependency-injection": "^3.4|^4.0|^5.0", - "symfony/finder": "~2.8|~3.0|~4.0|^5.0", - "symfony/http-kernel": "^4.4", - "symfony/intl": "^3.4|^4.0|^5.0", + "symfony/config": "^4.4|^5.0", + "symfony/console": "^4.4|^5.0", + "symfony/dependency-injection": "^5.0", + "symfony/finder": "^4.4|^5.0", + "symfony/http-kernel": "^5.0", + "symfony/intl": "^4.4|^5.0", "symfony/service-contracts": "^1.1.2|^2", - "symfony/yaml": "^3.4|^4.0|^5.0" + "symfony/yaml": "^4.4|^5.0" }, "suggest": { "psr/log-implementation": "To use logging capability in translator", @@ -5422,7 +5810,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -5463,7 +5851,7 @@ "type": "tidelift" } ], - "time": "2020-05-30T20:06:45+00:00" + "time": "2020-05-30T20:35:19+00:00" }, { "name": "symfony/translation-contracts", @@ -5538,33 +5926,32 @@ }, { "name": "symfony/var-dumper", - "version": "v4.4.9", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "56b3aa5eab0ac6720dcd559fd1d590ce301594ac" + "reference": "46a942903059b0b05e601f00eb64179e05578c0f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/56b3aa5eab0ac6720dcd559fd1d590ce301594ac", - "reference": "56b3aa5eab0ac6720dcd559fd1d590ce301594ac", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/46a942903059b0b05e601f00eb64179e05578c0f", + "reference": "46a942903059b0b05e601f00eb64179e05578c0f", "shasum": "" }, "require": { - "php": ">=7.1.3", + "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php72": "~1.5", "symfony/polyfill-php80": "^1.15" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", - "symfony/console": "<3.4" + "phpunit/phpunit": "<5.4.3", + "symfony/console": "<4.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^3.4|^4.0|^5.0", + "symfony/console": "^4.4|^5.0", "symfony/process": "^4.4|^5.0", - "twig/twig": "^1.34|^2.4|^3.0" + "twig/twig": "^2.4|^3.0" }, "suggest": { "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", @@ -5577,7 +5964,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.4-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -5625,7 +6012,7 @@ "type": "tidelift" } ], - "time": "2020-05-30T20:06:45+00:00" + "time": "2020-05-30T20:35:19+00:00" }, { "name": "tightenco/collect", @@ -5793,27 +6180,28 @@ }, { "name": "vlucas/phpdotenv", - "version": "v3.6.5", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/vlucas/phpdotenv.git", - "reference": "8b64814b356b96a90d2bc942b152c80d8888b8d4" + "reference": "db63b2ea280fdcf13c4ca392121b0b2450b51193" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/8b64814b356b96a90d2bc942b152c80d8888b8d4", - "reference": "8b64814b356b96a90d2bc942b152c80d8888b8d4", + "url": "https://api.github.com/repos/vlucas/phpdotenv/zipball/db63b2ea280fdcf13c4ca392121b0b2450b51193", + "reference": "db63b2ea280fdcf13c4ca392121b0b2450b51193", "shasum": "" }, "require": { - "php": "^5.4 || ^7.0 || ^8.0", - "phpoption/phpoption": "^1.5", - "symfony/polyfill-ctype": "^1.9" + "php": "^5.5.9 || ^7.0 || ^8.0", + "phpoption/phpoption": "^1.7.3", + "symfony/polyfill-ctype": "^1.16" }, "require-dev": { + "bamarni/composer-bin-plugin": "^1.4.1", "ext-filter": "*", "ext-pcre": "*", - "phpunit/phpunit": "^4.8.35 || ^5.0 || ^6.0 || ^7.0" + "phpunit/phpunit": "^4.8.35 || ^5.7.27 || ^6.5.6 || ^7.0" }, "suggest": { "ext-filter": "Required to use the boolean validator.", @@ -5822,7 +6210,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.6-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -5862,7 +6250,73 @@ "type": "tidelift" } ], - "time": "2020-05-23T09:42:03+00:00" + "time": "2020-06-07T18:25:35+00:00" + }, + { + "name": "voku/portable-ascii", + "version": "1.5.2", + "source": { + "type": "git", + "url": "https://github.com/voku/portable-ascii.git", + "reference": "618631dc601d8eb6ea0a9fbf654ec82f066c4e97" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/voku/portable-ascii/zipball/618631dc601d8eb6ea0a9fbf654ec82f066c4e97", + "reference": "618631dc601d8eb6ea0a9fbf654ec82f066c4e97", + "shasum": "" + }, + "require": { + "php": ">=7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "~6.0 || ~7.0" + }, + "suggest": { + "ext-intl": "Use Intl for transliterator_transliterate() support" + }, + "type": "library", + "autoload": { + "psr-4": { + "voku\\": "src/voku/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Lars Moelleken", + "homepage": "http://www.moelleken.org/" + } + ], + "description": "Portable ASCII library - performance optimized (ascii) string functions for php.", + "homepage": "https://github.com/voku/portable-ascii", + "keywords": [ + "ascii", + "clean", + "php" + ], + "funding": [ + { + "url": "https://www.paypal.me/moelleken", + "type": "custom" + }, + { + "url": "https://github.com/voku", + "type": "github" + }, + { + "url": "https://www.patreon.com/voku", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/voku/portable-ascii", + "type": "tidelift" + } + ], + "time": "2020-06-15T23:49:30+00:00" } ], "packages-dev": [ @@ -6635,16 +7089,16 @@ }, { "name": "filp/whoops", - "version": "2.7.2", + "version": "2.7.3", "source": { "type": "git", "url": "https://github.com/filp/whoops.git", - "reference": "17d0d3f266c8f925ebd035cd36f83cf802b47d4a" + "reference": "5d5fe9bb3d656b514d455645b3addc5f7ba7714d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/filp/whoops/zipball/17d0d3f266c8f925ebd035cd36f83cf802b47d4a", - "reference": "17d0d3f266c8f925ebd035cd36f83cf802b47d4a", + "url": "https://api.github.com/repos/filp/whoops/zipball/5d5fe9bb3d656b514d455645b3addc5f7ba7714d", + "reference": "5d5fe9bb3d656b514d455645b3addc5f7ba7714d", "shasum": "" }, "require": { @@ -6692,7 +7146,7 @@ "throwable", "whoops" ], - "time": "2020-05-05T12:28:07+00:00" + "time": "2020-06-14T09:00:00+00:00" }, { "name": "fzaninotto/faker", @@ -7122,16 +7576,16 @@ }, { "name": "ocramius/package-versions", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/Ocramius/PackageVersions.git", - "reference": "421679846270a5772534828013a93be709fb13df" + "reference": "94c9d42a466c57f91390cdd49c81313264f49d85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/421679846270a5772534828013a93be709fb13df", - "reference": "421679846270a5772534828013a93be709fb13df", + "url": "https://api.github.com/repos/Ocramius/PackageVersions/zipball/94c9d42a466c57f91390cdd49c81313264f49d85", + "reference": "94c9d42a466c57f91390cdd49c81313264f49d85", "shasum": "" }, "require": { @@ -7143,7 +7597,7 @@ "doctrine/coding-standard": "^7.0.2", "ext-zip": "^1.15.0", "infection/infection": "^0.15.3", - "phpunit/phpunit": "^9.0.1", + "phpunit/phpunit": "^9.1.1", "vimeo/psalm": "^3.9.3" }, "type": "composer-plugin", @@ -7179,7 +7633,7 @@ "type": "tidelift" } ], - "time": "2020-04-06T17:43:35+00:00" + "time": "2020-06-22T14:15:44+00:00" }, { "name": "openlss/lib-array2xml", @@ -7232,29 +7686,29 @@ }, { "name": "orchestra/testbench", - "version": "v4.8.0", + "version": "v5.3.0", "source": { "type": "git", "url": "https://github.com/orchestral/testbench.git", - "reference": "8f299c614927de8e1435967606d01078cc4e351c" + "reference": "57129325ae77e9e3fa6a577b4c3544398af1620e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench/zipball/8f299c614927de8e1435967606d01078cc4e351c", - "reference": "8f299c614927de8e1435967606d01078cc4e351c", + "url": "https://api.github.com/repos/orchestral/testbench/zipball/57129325ae77e9e3fa6a577b4c3544398af1620e", + "reference": "57129325ae77e9e3fa6a577b4c3544398af1620e", "shasum": "" }, "require": { - "laravel/framework": "^6.18", - "mockery/mockery": "~1.2.3 || ^1.3.1", - "orchestra/testbench-core": "^4.7", - "php": ">=7.2", - "phpunit/phpunit": "^8.3 || ^9.0" + "laravel/framework": "^7.10", + "mockery/mockery": "^1.3.1", + "orchestra/testbench-core": "^5.1.4", + "php": ">=7.2.5", + "phpunit/phpunit": "^8.4 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "6.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -7288,43 +7742,44 @@ "type": "patreon" } ], - "time": "2020-04-28T00:48:09+00:00" + "time": "2020-05-30T01:04:58+00:00" }, { "name": "orchestra/testbench-core", - "version": "v4.7.1", + "version": "v5.1.4", "source": { "type": "git", "url": "https://github.com/orchestral/testbench-core.git", - "reference": "c8e9ce9578fe13c075751d81f23dc2c3bb37a134" + "reference": "41ebd765f5b3f1aba366cc6b2f5b3856a1715519" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/c8e9ce9578fe13c075751d81f23dc2c3bb37a134", - "reference": "c8e9ce9578fe13c075751d81f23dc2c3bb37a134", + "url": "https://api.github.com/repos/orchestral/testbench-core/zipball/41ebd765f5b3f1aba366cc6b2f5b3856a1715519", + "reference": "41ebd765f5b3f1aba366cc6b2f5b3856a1715519", "shasum": "" }, "require": { "fzaninotto/faker": "^1.9.1", - "php": ">=7.2" + "php": ">=7.2.5" }, "require-dev": { - "laravel/framework": "^6.18.0", - "laravel/laravel": "6.x-dev", - "mockery/mockery": "~1.2.3 || ^1.3.1", - "phpunit/phpunit": "^8.3 || ^9.0" + "laravel/framework": "^7.1", + "laravel/laravel": "dev-master", + "mockery/mockery": "^1.3.1", + "orchestra/canvas": "^5.0", + "phpunit/phpunit": "^8.4 || ^9.0" }, "suggest": { - "laravel/framework": "Required for testing (^6.18).", - "mockery/mockery": "Allow using Mockery for testing (^1.2.3).", - "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^4.0).", - "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^4.0).", - "phpunit/phpunit": "Allow using PHPUnit for testing (^8.3)." + "laravel/framework": "Required for testing (^7.1).", + "mockery/mockery": "Allow using Mockery for testing (^1.3.1).", + "orchestra/testbench-browser-kit": "Allow using legacy Laravel BrowserKit for testing (^5.0).", + "orchestra/testbench-dusk": "Allow using Laravel Dusk for testing (^5.0).", + "phpunit/phpunit": "Allow using PHPUnit for testing (^8.4 || ^9.0)." }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -7363,7 +7818,7 @@ "type": "patreon" } ], - "time": "2020-04-11T10:37:21+00:00" + "time": "2020-05-02T13:35:10+00:00" }, { "name": "phar-io/manifest", @@ -7571,16 +8026,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "7462d5f123dfc080dfdf26897032a6513644fc95" + "reference": "30441f2752e493c639526b215ed81d54f369d693" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/7462d5f123dfc080dfdf26897032a6513644fc95", - "reference": "7462d5f123dfc080dfdf26897032a6513644fc95", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/30441f2752e493c639526b215ed81d54f369d693", + "reference": "30441f2752e493c639526b215ed81d54f369d693", "shasum": "" }, "require": { @@ -7594,7 +8049,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-1.x": "1.x-dev" } }, "autoload": { @@ -7613,7 +8068,7 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-02-18T18:59:58+00:00" + "time": "2020-06-19T20:22:09+00:00" }, { "name": "phpspec/prophecy", @@ -7932,16 +8387,16 @@ }, { "name": "phpunit/phpunit", - "version": "8.5.5", + "version": "8.5.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "63dda3b212a0025d380a745f91bdb4d8c985adb7" + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/63dda3b212a0025d380a745f91bdb4d8c985adb7", - "reference": "63dda3b212a0025d380a745f91bdb4d8c985adb7", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997", + "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997", "shasum": "" }, "require": { @@ -8021,24 +8476,24 @@ "type": "github" } ], - "time": "2020-05-22T13:51:52+00:00" + "time": "2020-06-22T07:06:58+00:00" }, { "name": "psalm/plugin-laravel", - "version": "v1.2.1", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/psalm/psalm-plugin-laravel.git", - "reference": "db2f1a2769e383f820eb5e38dd4a0d58fdba069d" + "reference": "5315836374c510aa615debbbb9e7882063f6bb24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/psalm/psalm-plugin-laravel/zipball/db2f1a2769e383f820eb5e38dd4a0d58fdba069d", - "reference": "db2f1a2769e383f820eb5e38dd4a0d58fdba069d", + "url": "https://api.github.com/repos/psalm/psalm-plugin-laravel/zipball/5315836374c510aa615debbbb9e7882063f6bb24", + "reference": "5315836374c510aa615debbbb9e7882063f6bb24", "shasum": "" }, "require": { - "barryvdh/laravel-ide-helper": "^2.6", + "barryvdh/laravel-ide-helper": "^2.7", "ext-simplexml": "*", "illuminate/container": "5.8.* || ^6.0 || ^7.0", "illuminate/contracts": "5.8.* || ^6.0 || ^7.0", @@ -8046,19 +8501,22 @@ "illuminate/http": "5.8.* || ^6.0 || ^7.0", "illuminate/support": "5.8.* || ^6.0 || ^7.0", "orchestra/testbench": "^3.8 || ^4.0 || ^5.0", - "php": "^7.1.3|^8", - "vimeo/psalm": "^3.8.2 || dev-master" + "php": "^7.2|^8", + "vimeo/psalm": "^3.11.6" }, "require-dev": { - "codeception/codeception": "^4.1", + "codeception/codeception": "^4.1.6", "codeception/module-asserts": "^1.0.0", "codeception/module-phpbrowser": "^1.0.0", "slevomat/coding-standard": "^6.2", "squizlabs/php_codesniffer": "*", - "weirdan/codeception-psalm-module": "^0.7.1" + "weirdan/codeception-psalm-module": "^0.7.2" }, "type": "psalm-plugin", "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, "psalm": { "pluginClass": "Psalm\\LaravelPlugin\\Plugin" } @@ -8079,7 +8537,7 @@ } ], "description": "A Laravel plugin for Psalm", - "time": "2020-05-12T05:52:51+00:00" + "time": "2020-06-18T14:00:27+00:00" }, { "name": "roave/security-advisories", @@ -8087,12 +8545,12 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "de6fda3af9b36c77fdeb62b968157032f7111b09" + "reference": "6d2e5ab854782830911ddd33b7d4649b9f18c10f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/de6fda3af9b36c77fdeb62b968157032f7111b09", - "reference": "de6fda3af9b36c77fdeb62b968157032f7111b09", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/6d2e5ab854782830911ddd33b7d4649b9f18c10f", + "reference": "6d2e5ab854782830911ddd33b7d4649b9f18c10f", "shasum": "" }, "conflict": { @@ -8101,13 +8559,14 @@ "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", "amphp/artax": "<1.0.6|>=2,<2.0.6", "amphp/http": "<1.0.1", + "amphp/http-client": ">=4,<4.4", "api-platform/core": ">=2.2,<2.2.10|>=2.3,<2.3.6", "asymmetricrypt/asymmetricrypt": ">=0,<9.9.99", "aws/aws-sdk-php": ">=3,<3.2.1", "bagisto/bagisto": "<0.1.5", "barrelstrength/sprout-base-email": "<1.2.7", "barrelstrength/sprout-forms": "<3.9", - "bolt/bolt": "<3.6.10", + "bolt/bolt": "<3.7.1", "brightlocal/phpwhois": "<=4.2.5", "buddypress/buddypress": "<5.1.2", "bugsnag/bugsnag-laravel": ">=2,<2.0.2", @@ -8135,8 +8594,8 @@ "doctrine/orm": ">=2,<2.4.8|>=2.5,<2.5.1", "dolibarr/dolibarr": "<11.0.4", "dompdf/dompdf": ">=0.6,<0.6.2", - "drupal/core": ">=7,<7.70|>=8,<8.7.14|>=8.8,<8.8.6", - "drupal/drupal": ">=7,<7.70|>=8,<8.7.14|>=8.8,<8.8.6", + "drupal/core": ">=7,<7.72|>=8,<8.8.8|>=8.9,<8.9.1|>=9,<9.0.1", + "drupal/drupal": ">=7,<7.72|>=8,<8.8.8|>=8.9,<8.9.1|>=9,<9.0.1", "endroid/qr-code-bundle": "<3.4.2", "enshrined/svg-sanitize": "<0.13.1", "erusev/parsedown": "<1.7.2", @@ -8199,6 +8658,7 @@ "pear/archive_tar": "<1.4.4", "phpfastcache/phpfastcache": ">=5,<5.0.13", "phpmailer/phpmailer": "<6.1.6", + "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<4.9.2", "phpoffice/phpexcel": "<1.8.2", "phpoffice/phpspreadsheet": "<1.8", @@ -8362,7 +8822,7 @@ "type": "tidelift" } ], - "time": "2020-06-04T00:00:55+00:00" + "time": "2020-06-19T13:23:43+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -9084,7 +9544,7 @@ }, { "name": "symfony/filesystem", - "version": "v5.1.0", + "version": "v5.1.2", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", @@ -9188,22 +9648,22 @@ }, { "name": "vimeo/psalm", - "version": "3.11.5", + "version": "3.12.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "3c60609c218d4d4b3b257728b8089094e5c6c6c2" + "reference": "d46283075d76ed244f7825b378eeb1cee246af73" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/3c60609c218d4d4b3b257728b8089094e5c6c6c2", - "reference": "3c60609c218d4d4b3b257728b8089094e5c6c6c2", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/d46283075d76ed244f7825b378eeb1cee246af73", + "reference": "d46283075d76ed244f7825b378eeb1cee246af73", "shasum": "" }, "require": { "amphp/amp": "^2.1", "amphp/byte-stream": "^1.5", - "composer/semver": "^1.4", + "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/xdebug-handler": "^1.1", "ext-dom": "*", "ext-json": "*", @@ -9281,20 +9741,20 @@ "inspection", "php" ], - "time": "2020-05-27T15:12:09+00:00" + "time": "2020-06-22T15:39:46+00:00" }, { "name": "webmozart/assert", - "version": "1.8.0", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6" + "reference": "9dc4f203e36f2b486149058bade43c851dd97451" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/ab2cb0b3b559010b75981b1bdce728da3ee90ad6", - "reference": "ab2cb0b3b559010b75981b1bdce728da3ee90ad6", + "url": "https://api.github.com/repos/webmozart/assert/zipball/9dc4f203e36f2b486149058bade43c851dd97451", + "reference": "9dc4f203e36f2b486149058bade43c851dd97451", "shasum": "" }, "require": { @@ -9302,6 +9762,7 @@ "symfony/polyfill-ctype": "^1.8" }, "conflict": { + "phpstan/phpstan": "<0.12.20", "vimeo/psalm": "<3.9.1" }, "require-dev": { @@ -9329,7 +9790,7 @@ "check", "validate" ], - "time": "2020-04-18T12:12:48+00:00" + "time": "2020-06-16T10:16:42+00:00" }, { "name": "webmozart/glob", @@ -9428,13 +9889,12 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "bunq/sdk_php": 20, "roave/security-advisories": 20 }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.3.0", + "php": ">=7.4.0", "ext-bcmath": "*", "ext-curl": "*", "ext-fileinfo": "*", diff --git a/config/app.php b/config/app.php index 3e5f86562a..a5774e4eba 100644 --- a/config/app.php +++ b/config/app.php @@ -21,7 +21,6 @@ declare(strict_types=1); -use FireflyIII\Providers\ImportServiceProvider; use FireflyIII\Support\Facades\Telemetry; return [ @@ -97,7 +96,6 @@ return [ FireflyIII\Providers\TagServiceProvider::class, FireflyIII\Providers\AdminServiceProvider::class, FireflyIII\Providers\RecurringServiceProvider::class, - ImportServiceProvider::class, ], 'aliases' => [ 'App' => Illuminate\Support\Facades\App::class, @@ -149,6 +147,24 @@ return [ 'Google2FA' => PragmaRX\Google2FALaravel\Facade::class, 'Twig' => TwigBridge\Facade\Twig::class, + 'Arr' => Illuminate\Support\Arr::class, + 'Http' => Illuminate\Support\Facades\Http::class, + 'Str' => Illuminate\Support\Str::class, ], + 'asset_url' => env('ASSET_URL', null), + + /* + |-------------------------------------------------------------------------- + | Faker Locale + |-------------------------------------------------------------------------- + | + | This locale will be used by the Faker PHP library when generating fake + | data for your database seeds. For example, this will be used to get + | localized telephone numbers, street address information and more. + | + */ + + 'faker_locale' => 'en_US', + ]; diff --git a/config/auth.php b/config/auth.php index 077aac8e09..189babdc0a 100644 --- a/config/auth.php +++ b/config/auth.php @@ -34,7 +34,7 @@ return [ */ 'defaults' => [ - 'guard' => 'web', + 'guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), 'passwords' => 'users', ], @@ -56,11 +56,15 @@ return [ */ 'guards' => [ - 'web' => [ + 'web' => [ 'driver' => 'session', 'provider' => 'users', ], - 'api' => [ + 'remote_user_guard' => [ + 'driver' => 'remote_user_guard', + 'provider' => 'remote_user_provider', + ], + 'api' => [ 'driver' => 'passport', 'provider' => 'users', ], @@ -84,10 +88,14 @@ return [ */ 'providers' => [ - 'users' => [ + 'users' => [ 'driver' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), //'adldap', 'model' => FireflyIII\User::class, ], + 'remote_user_provider' => [ + 'driver' => 'remote_user_provider', + 'model' => FireflyIII\User::class, + ], ], /* @@ -113,4 +121,18 @@ return [ ], ], + + /* + |-------------------------------------------------------------------------- + | Password Confirmation Timeout + |-------------------------------------------------------------------------- + | + | Here you may define the amount of seconds before a password confirmation + | times out and the user is prompted to re-enter their password via the + | confirmation screen. By default, the timeout lasts for three hours. + | + */ + + 'password_timeout' => 10800, + ]; diff --git a/config/cache.php b/config/cache.php index c992d39a84..96f9a2ae9b 100644 --- a/config/cache.php +++ b/config/cache.php @@ -56,6 +56,7 @@ return [ 'array' => [ 'driver' => 'array', + 'serialize' => false, ], 'database' => [ @@ -93,6 +94,15 @@ return [ 'connection' => 'default', ], + + 'dynamodb' => [ + 'driver' => 'dynamodb', + 'key' => env('AWS_ACCESS_KEY_ID'), + 'secret' => env('AWS_SECRET_ACCESS_KEY'), + 'region' => env('AWS_DEFAULT_REGION', 'us-east-1'), + 'table' => env('DYNAMODB_CACHE_TABLE', 'cache'), + 'endpoint' => env('DYNAMODB_ENDPOINT'), + ], ], /* @@ -108,4 +118,5 @@ return [ 'prefix' => env('CACHE_PREFIX', 'firefly'), + ]; diff --git a/config/csv.php b/config/csv.php deleted file mode 100644 index c459762b00..0000000000 --- a/config/csv.php +++ /dev/null @@ -1,430 +0,0 @@ -. - */ - -declare(strict_types=1); - -use FireflyIII\Import\Specifics\AbnAmroDescription; -use FireflyIII\Import\Specifics\Belfius; -use FireflyIII\Import\Specifics\IngBelgium; -use FireflyIII\Import\Specifics\IngDescription; -use FireflyIII\Import\Specifics\PresidentsChoice; -use FireflyIII\Import\Specifics\SnsDescription; - -return [ - /* - * Configuration for the CSV specifics. - */ - 'import_specifics' => [ - 'IngDescription' => IngDescription::class, - 'AbnAmroDescription' => AbnAmroDescription::class, - 'SnsDescription' => SnsDescription::class, - 'PresidentsChoice' => PresidentsChoice::class, - 'Belfius' => Belfius::class, - 'IngBelgium' => IngBelgium::class, - ], - - /* - * Configuration for possible column roles. - * - * The key is the short name for the column role. There are five values, which mean this: - * - * 'mappable' - * Whether or not the value in the CSV column can be linked to an existing value in your - * Firefly database. For example: account names can be linked to existing account names you have already - * so double entries cannot occur. This process is called "mapping". You have to make each unique value in your - * CSV file to an existing entry in your database. For example, map all account names in your CSV file to existing - * accounts. If you have an entry that does not exist in your database, you can set Firefly to ignore it, and it will - * create it. - * - * 'pre-process-map' - * In the case of tags, there are multiple values in one csv column (for example: "expense groceries snack" in one column). - * This means the content of the column must be "pre processed" aka split in parts so the importer can work with the data. - * - * 'pre-process-mapper' - * This is the class that will actually do the pre-processing. - * - * 'field' - * I don't believe this value is used any more, but I am not sure. - * - * 'converter' - * The converter is a class in app/Import/Converter that converts the given value into an object Firefly understands. - * The CategoryName converter can convert a category name into an actual category. This converter will take a mapping - * into account: if you mapped "Groceries" to category "Groceries" the converter will simply return "Groceries" instead of - * trying to make a new category also named Groceries. - * - * 'mapper' - * When you map data (see "mappable") you need a list of stuff you can map to. If you say a certain column is mappable - * and the column contains "category names", the mapper will be "Category" and it will give you a list of possible categories. - * This way the importer always presents you with a valid list of things to map to. - * - * - * - */ - 'import_roles' => [ - '_ignore' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'field' => 'ignored', - 'converter' => 'Ignore', - 'mapper' => null, - - ], - 'bill-id' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'bill', - 'converter' => 'BillId', - 'mapper' => 'Bills', - ], - 'note' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'field' => 'note', - 'converter' => 'Note', - ], - 'bill-name' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'bill', - 'converter' => 'BillName', - 'mapper' => 'Bills', - ], - 'currency-id' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'currency', - 'converter' => 'CurrencyId', - 'mapper' => 'TransactionCurrencies', - ], - 'currency-name' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'CurrencyName', - 'field' => 'currency', - 'mapper' => 'TransactionCurrencies', - ], - 'currency-code' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'CurrencyCode', - 'field' => 'currency', - 'mapper' => 'TransactionCurrencies', - ], - 'foreign-currency-code' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'CurrencyCode', - 'field' => 'foreign_currency', - 'mapper' => 'TransactionCurrencies', - ], - 'external-id' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'ExternalId', - 'field' => 'external-id', - ], - - 'currency-symbol' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'CurrencySymbol', - 'field' => 'currency', - 'mapper' => 'TransactionCurrencies', - ], - 'description' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'description', - ], - 'date-transaction' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Date', - 'field' => 'date', - ], - 'date-interest' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Date', - 'field' => 'date-interest', - ], - 'date-book' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Date', - 'field' => 'date-book', - ], - 'date-process' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Date', - 'field' => 'date-process', - ], - 'date-due' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Date', - 'field' => 'date-due', - ], - 'date-payment' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Date', - 'field' => 'date-payment', - ], - 'date-invoice' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Date', - 'field' => 'date-invoice', - ], - 'budget-id' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'BudgetId', - 'field' => 'budget', - 'mapper' => 'Budgets', - ], - 'budget-name' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'BudgetName', - 'field' => 'budget', - 'mapper' => 'Budgets', - ], - 'rabo-debit-credit' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'BankDebitCredit', - 'field' => 'amount-modifier', - ], - 'ing-debit-credit' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'BankDebitCredit', - 'field' => 'amount-modifier', - ], - 'generic-debit-credit' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'BankDebitCredit', - 'field' => 'amount-modifier', - ], - 'category-id' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'CategoryId', - 'field' => 'category', - 'mapper' => 'Categories', - ], - 'category-name' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'converter' => 'CategoryName', - 'field' => 'category', - 'mapper' => 'Categories', - ], - 'tags-comma' => [ - 'mappable' => false, - 'pre-process-map' => true, - 'pre-process-mapper' => 'TagsComma', - 'field' => 'tags', - 'converter' => 'TagsComma', - 'mapper' => 'Tags', - ], - 'tags-space' => [ - 'mappable' => false, - 'pre-process-map' => true, - 'pre-process-mapper' => 'TagsSpace', - 'field' => 'tags', - 'converter' => 'TagsSpace', - 'mapper' => 'Tags', - ], - 'account-id' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'asset-account-id', - 'converter' => 'AccountId', - 'mapper' => 'AssetAccounts', - ], - 'account-name' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'asset-account-name', - 'converter' => 'AssetAccountName', - 'mapper' => 'AssetAccounts', - ], - 'account-iban' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'asset-account-iban', - 'converter' => 'AssetAccountIban', - 'mapper' => 'AssetAccountIbans', - - ], - 'account-number' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'asset-account-number', - 'converter' => 'AssetAccountNumber', - 'mapper' => 'AssetAccounts', - ], - 'account-bic' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'field' => 'asset-account-bic', - 'converter' => 'AccountBic', - ], - 'opposing-id' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'opposing-account-id', - 'converter' => 'AccountId', - 'mapper' => 'OpposingAccounts', - ], - 'opposing-bic' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'field' => 'opposing-account-bic', - 'converter' => 'AccountBic', - ], - 'opposing-name' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'opposing-account-name', - 'converter' => 'OpposingAccountName', - 'mapper' => 'OpposingAccounts', - ], - 'opposing-iban' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'opposing-account-iban', - 'converter' => 'OpposingAccountIban', - 'mapper' => 'OpposingAccountIbans', - ], - 'opposing-number' => [ - 'mappable' => true, - 'pre-process-map' => false, - 'field' => 'opposing-account-number', - 'converter' => 'OpposingAccountNumber', - 'mapper' => 'OpposingAccounts', - ], - 'amount' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Amount', - 'field' => 'amount', - ], - 'amount_debit' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'AmountDebit', - 'field' => 'amount_debit', - ], - 'amount_credit' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'AmountCredit', - 'field' => 'amount_credit', - ], - 'amount_negated' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'AmountNegated', - 'field' => 'amount_negated', - ], - 'amount_foreign' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Amount', - 'field' => 'amount_foreign', - ], - - // SEPA end to end ID - 'sepa_ct_id' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_ct_id', - ], - // SEPA opposing account identifier - 'sepa_ct_op' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_ct_op', - ], - // SEPA Direct Debit Mandate Identifier - 'sepa_db' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_db', - ], - // SEPA clearing code - 'sepa_cc' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_cc', - ], - // SEPA country - 'sepa_country' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_country', - ], - // SEPA external purpose - 'sepa_ep' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_ep', - ], - // SEPA creditor identifier - 'sepa_ci' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_ci', - ], - // SEPA Batch ID - 'sepa_batch_id' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'sepa_batch', - ], - // Internal reference - 'internal-reference' => [ - 'mappable' => false, - 'pre-process-map' => false, - 'converter' => 'Description', - 'field' => 'internal_reference', - ], - ], - - // number of example rows: - 'example_rows' => 5, -]; diff --git a/config/firefly.php b/config/firefly.php index 61dde484a5..b265566943 100644 --- a/config/firefly.php +++ b/config/firefly.php @@ -30,8 +30,8 @@ use FireflyIII\Models\Bill; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\Category; -use FireflyIII\Models\ImportJob; use FireflyIII\Models\LinkType; +use FireflyIII\Models\ObjectGroup; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Preference; use FireflyIII\Models\Recurrence; @@ -53,7 +53,6 @@ use FireflyIII\Support\Binder\CLIToken; use FireflyIII\Support\Binder\ConfigurationName; use FireflyIII\Support\Binder\CurrencyCode; use FireflyIII\Support\Binder\Date; -use FireflyIII\Support\Binder\ImportProvider; use FireflyIII\Support\Binder\JournalList; use FireflyIII\Support\Binder\TagList; use FireflyIII\Support\Binder\TagOrId; @@ -85,14 +84,14 @@ use FireflyIII\TransactionRules\Triggers\AmountMore; use FireflyIII\TransactionRules\Triggers\BudgetIs; use FireflyIII\TransactionRules\Triggers\CategoryIs; use FireflyIII\TransactionRules\Triggers\CurrencyIs; -use FireflyIII\TransactionRules\Triggers\ForeignCurrencyIs; -use FireflyIII\TransactionRules\Triggers\DateIs; -use FireflyIII\TransactionRules\Triggers\DateBefore; use FireflyIII\TransactionRules\Triggers\DateAfter; +use FireflyIII\TransactionRules\Triggers\DateBefore; +use FireflyIII\TransactionRules\Triggers\DateIs; use FireflyIII\TransactionRules\Triggers\DescriptionContains; use FireflyIII\TransactionRules\Triggers\DescriptionEnds; use FireflyIII\TransactionRules\Triggers\DescriptionIs; use FireflyIII\TransactionRules\Triggers\DescriptionStarts; +use FireflyIII\TransactionRules\Triggers\ForeignCurrencyIs; use FireflyIII\TransactionRules\Triggers\FromAccountContains; use FireflyIII\TransactionRules\Triggers\FromAccountEnds; use FireflyIII\TransactionRules\Triggers\FromAccountIs; @@ -143,50 +142,51 @@ return [ 'telemetry' => true, ], - 'encryption' => null === env('USE_ENCRYPTION') || true === env('USE_ENCRYPTION'), - 'version' => '5.2.8', - 'api_version' => '1.1.0', - 'db_version' => 13, - 'maxUploadSize' => 15242880, - 'send_error_message' => env('SEND_ERROR_MESSAGE', true), - 'site_owner' => env('SITE_OWNER', ''), - 'send_registration_mail' => env('SEND_REGISTRATION_MAIL', true), - 'demo_username' => env('DEMO_USERNAME', ''), - 'demo_password' => env('DEMO_PASSWORD', ''), - 'is_sandstorm' => env('IS_SANDSTORM', 'unknown'), - 'bunq_use_sandbox' => env('BUNQ_USE_SANDBOX', false), - 'fixer_api_key' => env('FIXER_API_KEY', ''), - 'mapbox_api_key' => env('MAPBOX_API_KEY', ''), - 'trusted_proxies' => env('TRUSTED_PROXIES', ''), - 'search_result_limit' => env('SEARCH_RESULT_LIMIT', 50), - 'send_report_journals' => envNonEmpty('SEND_REPORT_JOURNALS', true), - 'tracker_site_id' => env('TRACKER_SITE_ID', ''), - 'tracker_url' => env('TRACKER_URL', ''), - 'disable_frame_header' => env('DISABLE_FRAME_HEADER', false), - 'disable_csp_header' => env('DISABLE_CSP_HEADER', false), - 'login_provider' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), - 'cer_provider' => envNonEmpty('CER_PROVIDER', 'fixer'), - 'update_endpoint' => 'https://version.firefly-iii.org/index.json', - 'send_telemetry' => env('SEND_TELEMETRY', false), - 'telemetry_endpoint' => 'https://telemetry.firefly-iii.org', - 'update_minimum_age' => 6, - 'default_location' => [ + //'encryption' => null === env('USE_ENCRYPTION') || true === env('USE_ENCRYPTION'), + 'version' => '5.3.0-alpha.1', + 'api_version' => '1.2.0', + 'db_version' => 14, + 'maxUploadSize' => 15242880, + 'send_error_message' => env('SEND_ERROR_MESSAGE', true), + 'site_owner' => env('SITE_OWNER', ''), + 'send_registration_mail' => env('SEND_REGISTRATION_MAIL', true), + 'demo_username' => env('DEMO_USERNAME', ''), + 'demo_password' => env('DEMO_PASSWORD', ''), + 'is_sandstorm' => env('IS_SANDSTORM', 'unknown'), + 'fixer_api_key' => env('FIXER_API_KEY', ''), + 'mapbox_api_key' => env('MAPBOX_API_KEY', ''), + 'trusted_proxies' => env('TRUSTED_PROXIES', ''), + 'search_result_limit' => env('SEARCH_RESULT_LIMIT', 50), + 'send_report_journals' => envNonEmpty('SEND_REPORT_JOURNALS', true), + 'tracker_site_id' => env('TRACKER_SITE_ID', ''), + 'tracker_url' => env('TRACKER_URL', ''), + 'disable_frame_header' => env('DISABLE_FRAME_HEADER', false), + 'disable_csp_header' => env('DISABLE_CSP_HEADER', false), + 'login_provider' => envNonEmpty('LOGIN_PROVIDER', 'eloquent'), + 'authentication_guard' => envNonEmpty('AUTHENTICATION_GUARD', 'web'), + 'custom_logout_uri' => envNonEmpty('CUSTOM_LOGOUT_URI', ''), + 'cer_provider' => envNonEmpty('CER_PROVIDER', 'fixer'), + 'update_endpoint' => 'https://version.firefly-iii.org/index.json', + 'send_telemetry' => env('SEND_TELEMETRY', false), + 'telemetry_endpoint' => 'https://telemetry.firefly-iii.org', + 'layout' => env('FIREFLY_III_LAYOUT', 'v1'), + 'update_minimum_age' => 6, + 'default_location' => [ 'longitude' => env('MAP_DEFAULT_LONG', '5.916667'), 'latitude' => env('MAP_DEFAULT_LAT', '51.983333'), 'zoom_level' => env('MAP_DEFAULT_ZOOM', '6'), ], - 'valid_attachment_models' => [ + 'valid_attachment_models' => [ Account::class, Bill::class, Budget::class, Category::class, - ImportJob::class, PiggyBank::class, Tag::class, Transaction::class, TransactionJournal::class, ], - 'allowedMimes' => [ + 'allowedMimes' => [ /* plain files */ 'text/plain', @@ -248,7 +248,6 @@ return [ 'application/vnd.oasis.opendocument.image', ], 'list_length' => 10, - 'default_import_format' => 'csv', 'bill_periods' => ['weekly', 'monthly', 'quarterly', 'half-year', 'yearly'], 'accountRoles' => ['defaultAsset', 'sharedAsset', 'savingAsset', 'ccAsset', 'cashWalletAsset'], 'ccTypes' => [ @@ -411,6 +410,7 @@ return [ 'transactionType' => TransactionTypeModel::class, 'journalLink' => TransactionJournalLink::class, 'currency' => TransactionCurrency::class, + 'objectGroup' => ObjectGroup::class, 'piggyBank' => PiggyBank::class, 'preference' => Preference::class, 'tj' => TransactionJournal::class, @@ -418,12 +418,10 @@ return [ 'recurrence' => Recurrence::class, 'rule' => Rule::class, 'ruleGroup' => RuleGroup::class, - 'importJob' => ImportJob::class, 'transactionGroup' => TransactionGroup::class, 'user' => User::class, // strings - 'import_provider' => ImportProvider::class, 'currency_code' => CurrencyCode::class, // dates diff --git a/config/import.php b/config/import.php deleted file mode 100644 index 21f5d74422..0000000000 --- a/config/import.php +++ /dev/null @@ -1,172 +0,0 @@ -. - */ - -declare(strict_types=1); - -use FireflyIII\Import\JobConfiguration\BunqJobConfiguration; -use FireflyIII\Import\JobConfiguration\FakeJobConfiguration; -use FireflyIII\Import\JobConfiguration\FileJobConfiguration; -use FireflyIII\Import\JobConfiguration\FinTSJobConfiguration; -use FireflyIII\Import\JobConfiguration\SpectreJobConfiguration; -use FireflyIII\Import\JobConfiguration\YnabJobConfiguration; -use FireflyIII\Import\Prerequisites\BunqPrerequisites; -use FireflyIII\Import\Prerequisites\FakePrerequisites; -use FireflyIII\Import\Prerequisites\SpectrePrerequisites; -use FireflyIII\Import\Prerequisites\YnabPrerequisites; -use FireflyIII\Import\Routine\BunqRoutine; -use FireflyIII\Import\Routine\FakeRoutine; -use FireflyIII\Import\Routine\FileRoutine; -use FireflyIII\Import\Routine\FinTSRoutine; -use FireflyIII\Import\Routine\SpectreRoutine; -use FireflyIII\Import\Routine\YnabRoutine; -use FireflyIII\Support\Import\Routine\File\CSVProcessor; - -return [ - // these import providers are available: - 'enabled' => [ - 'fake' => true, - 'file' => false, - 'bunq' => false, - 'spectre' => true, - 'ynab' => false, - 'plaid' => false, - 'quovo' => false, - 'yodlee' => false, - 'fints' => false, - 'bad' => false, // always disabled - ], - // demo user can use these import providers (when enabled): - 'allowed_for_demo' => [ - 'fake' => true, - 'file' => false, - 'bunq' => false, - 'spectre' => false, - 'ynab' => false, - 'plaid' => false, - 'quovo' => false, - 'yodlee' => false, - 'fints' => false, - ], - // a normal user user can use these import providers (when enabled): - 'allowed_for_user' => [ - 'fake' => false, - 'file' => true, - 'bunq' => false, - 'spectre' => true, - 'ynab' => true, - 'plaid' => true, - 'quovo' => true, - 'yodlee' => true, - 'fints' => true, - ], - // some providers have pre-requisites. - 'has_prereq' => [ - 'fake' => true, - 'file' => false, - 'bunq' => false, - 'spectre' => true, - 'ynab' => true, - 'plaid' => true, - 'quovo' => true, - 'yodlee' => true, - 'fints' => false, - ], - // if so, there must be a class to handle them. - 'prerequisites' => [ - 'fake' => FakePrerequisites::class, - 'file' => false, - 'bunq' => BunqPrerequisites::class, - 'spectre' => SpectrePrerequisites::class, - 'ynab' => YnabPrerequisites::class, - 'plaid' => false, - 'quovo' => false, - 'yodlee' => false, - 'fints' => false, - ], - // some providers may need extra configuration per job - 'has_job_config' => [ - 'fake' => true, - 'file' => true, - 'bunq' => true, - 'spectre' => true, - 'ynab' => true, - 'plaid' => false, - 'quovo' => false, - 'yodlee' => false, - 'fints' => true, - ], - // if so, this is the class that handles it. - 'configuration' => [ - 'fake' => FakeJobConfiguration::class, - 'file' => FileJobConfiguration::class, - 'bunq' => BunqJobConfiguration::class, - 'spectre' => SpectreJobConfiguration::class, - 'ynab' => YnabJobConfiguration::class, - 'plaid' => false, - 'quovo' => false, - 'yodlee' => false, - 'fints' => FinTSJobConfiguration::class, - ], - // this is the routine that runs the actual import. - 'routine' => [ - 'fake' => FakeRoutine::class, - 'file' => FileRoutine::class, - 'bunq' => BunqRoutine::class, - 'spectre' => SpectreRoutine::class, - 'ynab' => YnabRoutine::class, - 'plaid' => false, - 'quovo' => false, - 'yodlee' => false, - 'fints' => FinTSRoutine::class, - ], - - 'options' => [ - 'fake' => [], - 'file' => [ - 'import_formats' => ['csv'], // mt940 - 'default_import_format' => 'csv', - 'processors' => [ - 'csv' => CSVProcessor::class, - ], - ], - 'bunq' => [ - 'live' => [ - 'server' => 'api.bunq.com', - 'version' => 'v1', - ], - 'sandbox' => [ - 'server' => 'sandbox.public.api.bunq.com', // sandbox.public.api.bunq.com - api.bunq.com - 'version' => 'v1', - ], - ], - 'spectre' => [ - 'server' => 'www.saltedge.com', - ], - 'ynab' => [ - 'live' => 'api.youneedabudget.com', - 'version' => 'v1', - ], - 'plaid' => [], - 'quovo' => [], - 'yodlee' => [], - ], -]; diff --git a/config/mail.php b/config/mail.php index 1a3183e064..57d7998ba6 100644 --- a/config/mail.php +++ b/config/mail.php @@ -22,111 +22,60 @@ declare(strict_types=1); return [ - /* - |-------------------------------------------------------------------------- - | Mail Driver - |-------------------------------------------------------------------------- - | - | Laravel supports both SMTP and PHP's "mail" function as drivers for the - | sending of e-mail. You may specify which one you're using throughout - | your application here. By default, Laravel is setup for SMTP mail. - | - | Supported: "smtp", "sendmail", "mailgun", "mandrill", "ses", - | "sparkpost", "log", "array" - | - */ - 'driver' => envNonEmpty('MAIL_DRIVER', 'log'), +/* +|-------------------------------------------------------------------------- +| Default Mailer +|-------------------------------------------------------------------------- +| +| This option controls the default mailer that is used to send any email +| messages sent by your application. Alternative mailers may be setup +| and used as needed; however, this mailer will be used by default. +| +*/ + 'default' => env('MAIL_MAILER', 'smtp'), - /* - |-------------------------------------------------------------------------- - | SMTP Host Address - |-------------------------------------------------------------------------- - | - | Here you may provide the host address of the SMTP server used by your - | applications. A default option is provided that is compatible with - | the Mailgun mail service which will provide reliable deliveries. - | - */ + 'mailers' => [ + 'smtp' => [ + 'transport' => 'smtp', + 'host' => env('MAIL_HOST', 'smtp.mailtrap.io'), + 'port' => env('MAIL_PORT', 2525), + 'encryption' => env('MAIL_ENCRYPTION', 'tls'), + 'username' => env('MAIL_USERNAME'), + 'password' => env('MAIL_PASSWORD'), + 'timeout' => null, + ], - 'host' => env('MAIL_HOST', 'smtp.mailtrap.io'), + 'ses' => [ + 'transport' => 'ses', + ], - /* - |-------------------------------------------------------------------------- - | SMTP Host Port - |-------------------------------------------------------------------------- - | - | This is the SMTP port used by your application to deliver e-mails to - | users of the application. Like the host we have set this value to - | stay compatible with the Mailgun e-mail application by default. - | - */ + 'mailgun' => [ + 'transport' => 'mailgun', + ], - 'port' => env('MAIL_PORT', 2525), + 'postmark' => [ + 'transport' => 'postmark', + ], + + 'sendmail' => [ + 'transport' => 'sendmail', + 'path' => '/usr/sbin/sendmail -bs', + ], + 'log' => [ + 'transport' => 'log', + 'channel' => env('MAIL_LOG_CHANNEL', 'stack'), + 'level' => 'debug', + ], + + 'array' => [ + 'transport' => 'array', + ], + ], - /* - |-------------------------------------------------------------------------- - | Global "From" Address - |-------------------------------------------------------------------------- - | - | You may wish for all e-mails sent by your application to be sent from - | the same address. Here, you may specify a name and address that is - | used globally for all e-mails that are sent by your application. - | - */ 'from' => ['address' => envNonEmpty('MAIL_FROM', 'changeme@example.com'), 'name' => 'Firefly III Mailer'], - /* - |-------------------------------------------------------------------------- - | E-Mail Encryption Protocol - |-------------------------------------------------------------------------- - | - | Here you may specify the encryption protocol that should be used when - | the application send e-mail messages. A sensible default using the - | transport layer security protocol should provide great security. - | - */ - 'encryption' => env('MAIL_ENCRYPTION', 'tls'), - - /* - |-------------------------------------------------------------------------- - | SMTP Server Username - |-------------------------------------------------------------------------- - | - | If your SMTP server requires a username for authentication, you should - | set it here. This will get used to authenticate with your server on - | connection. You may also set the "password" value below this one. - | - */ - - 'username' => env('MAIL_USERNAME'), - - 'password' => env('MAIL_PASSWORD'), - - /* - |-------------------------------------------------------------------------- - | Sendmail System Path - |-------------------------------------------------------------------------- - | - | When using the "sendmail" driver to send e-mails, we will need to know - | the path to where Sendmail lives on this server. A default path has - | been provided here, which will work well on most of your systems. - | - */ - - 'sendmail' => '/usr/sbin/sendmail -bs', - - /* - |-------------------------------------------------------------------------- - | Markdown Mail Settings - |-------------------------------------------------------------------------- - | - | If you are using Markdown based email rendering, you may configure your - | theme and component paths here, allowing you to customize the design - | of the emails. Or, you may simply stick with the Laravel defaults! - | - */ 'markdown' => [ 'theme' => 'default', diff --git a/config/session.php b/config/session.php index 7458e597fa..09becf087b 100644 --- a/config/session.php +++ b/config/session.php @@ -34,7 +34,7 @@ return [ 'cookie' => 'firefly_session', 'path' => env('COOKIE_PATH', '/'), 'domain' => env('COOKIE_DOMAIN', null), - 'secure' => env('COOKIE_SECURE', false), + 'secure' => env('COOKIE_SECURE', null), 'http_only' => true, 'same_site' => null, ]; diff --git a/config/twigbridge.php b/config/twigbridge.php index 7e765f862f..7ceabb7a57 100644 --- a/config/twigbridge.php +++ b/config/twigbridge.php @@ -186,7 +186,7 @@ return [ 'ExpandedForm' => [ 'is_safe' => [ 'date', 'text', 'select', 'balance', 'optionsList', 'checkbox', 'amount', 'tags', 'integer', 'textarea', 'location', 'file', 'staticText', - 'password', 'nonSelectableAmount', 'number', 'amountNoCurrency', 'percentage', + 'password', 'nonSelectableAmount', 'number', 'amountNoCurrency', 'percentage','objectGroup' ], ], diff --git a/config/view.php b/config/view.php index 42b243edca..ce48cdcf8f 100644 --- a/config/view.php +++ b/config/view.php @@ -34,7 +34,7 @@ return [ */ 'paths' => [ - realpath(base_path('resources/views/v1')), + realpath(base_path(sprintf('resources/views/%s', env('FIREFLY_III_LAYOUT', 'v1')))), ], /* @@ -48,6 +48,6 @@ return [ | */ - 'compiled' => realpath(storage_path('framework/views/v1')), + 'compiled' => realpath(storage_path(sprintf('framework/views/%s', env('FIREFLY_III_LAYOUT', 'v1')))), ]; diff --git a/database/factories/ModelFactory.php b/database/factories/ModelFactory.php index d52f908a3c..8b0125216f 100644 --- a/database/factories/ModelFactory.php +++ b/database/factories/ModelFactory.php @@ -65,27 +65,6 @@ $factory->define( } ); -$factory->define( - FireflyIII\Models\ImportJob::class, - static function (Faker\Generator $faker) { - return [ - 'id' => $faker->numberBetween(1, 100), - 'user_id' => 1, - 'key' => $faker->words(1, true), - 'file_type' => 'csv', - 'status' => 'import_status_never_started', - 'configuration' => null, - 'extended_status' => [ - 'total_steps' => 0, - 'steps_done' => 0, - 'import_count' => 0, - 'importTag' => 0, - 'errors' => [], - ], - ]; - } -); - $factory->define( FireflyIII\Models\TransactionJournal::class, static function (Faker\Generator $faker) { diff --git a/database/migrations/2020_06_07_063612_changes_for_v530.php b/database/migrations/2020_06_07_063612_changes_for_v530.php new file mode 100644 index 0000000000..13de0ff70b --- /dev/null +++ b/database/migrations/2020_06_07_063612_changes_for_v530.php @@ -0,0 +1,54 @@ +increments('id'); + $table->integer('user_id', false, true); + $table->timestamps(); + $table->softDeletes(); + $table->string('title', 255); + $table->mediumInteger('order', false, true)->default(0); + $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade'); + } + ); + } + + if (!Schema::hasTable('object_groupables')) { + Schema::create( + 'object_groupables', static function (Blueprint $table) { + $table->integer('object_group_id'); + $table->integer('object_groupable_id', false, true); + $table->string('object_groupable_type', 255); + } + ); + } + } +} diff --git a/frontend/build.sh b/frontend/build.sh new file mode 100755 index 0000000000..58312c391b --- /dev/null +++ b/frontend/build.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# build translations. +php /sites/tools/firefly-iii-tools/cli.php ff3:json-translations --v2 + +# remove old stuff +rm -rf public/ +rm -rf ../public/fonts +rm -rf ../public/v2/js +rm -rf ../public/v2/css + +# build new stuff +npm run prod + +# move to right directory +# mv public/js ../public/v2 +# mv public/css ../public/v2 + +# also copy fonts +cp -r fonts ../public diff --git a/frontend/mix-manifest.json b/frontend/mix-manifest.json new file mode 100644 index 0000000000..dcf1d27f48 --- /dev/null +++ b/frontend/mix-manifest.json @@ -0,0 +1,11 @@ +{ + "/public/js/manifest.js": "/public/js/manifest.js", + "/public/js/manifest.js.map": "/public/js/manifest.js.map", + "/public/js/vendor.js": "/public/js/vendor.js", + "/public/js/vendor.js.map": "/public/js/vendor.js.map", + "/public/js/dashboard.js": "/public/js/dashboard.js", + "/public/css/app.css": "/public/css/app.css", + "/public/js/dashboard.js.map": "/public/js/dashboard.js.map", + "/public/js/register.js": "/public/js/register.js", + "/public/js/register.js.map": "/public/js/register.js.map" +} diff --git a/frontend/package-lock.json b/frontend/package-lock.json new file mode 100755 index 0000000000..ef7b4e7e9d --- /dev/null +++ b/frontend/package-lock.json @@ -0,0 +1,10390 @@ +{ + "requires": true, + "lockfileVersion": 1, + "dependencies": { + "@babel/code-frame": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.10.1.tgz", + "integrity": "sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw==", + "dev": true, + "requires": { + "@babel/highlight": "^7.10.1" + } + }, + "@babel/compat-data": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.10.1.tgz", + "integrity": "sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "semver": "^5.5.0" + } + }, + "@babel/core": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.10.2.tgz", + "integrity": "sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.2", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helpers": "^7.10.1", + "@babel/parser": "^7.10.2", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.2", + "convert-source-map": "^1.7.0", + "debug": "^4.1.0", + "gensync": "^1.0.0-beta.1", + "json5": "^2.1.2", + "lodash": "^4.17.13", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.10.2.tgz", + "integrity": "sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA==", + "dev": true, + "requires": { + "@babel/types": "^7.10.2", + "jsesc": "^2.5.1", + "lodash": "^4.17.13", + "source-map": "^0.5.0" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.1.tgz", + "integrity": "sha512-ewp3rvJEwLaHgyWGe4wQssC2vjks3E80WiUe2BpMb0KhreTjMROCbxXcEovTrbeGVdQct5VjQfrv9EgC+xMzCw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz", + "integrity": "sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-compilation-targets": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.2.tgz", + "integrity": "sha512-hYgOhF4To2UTB4LTaZepN/4Pl9LD4gfbJx8A34mqoluT8TLbof1mhUlYuNWTEebONa8+UlCC4X0TEXu7AOUyGA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.1", + "browserslist": "^4.12.0", + "invariant": "^2.2.4", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz", + "integrity": "sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1" + } + }, + "@babel/helper-create-regexp-features-plugin": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.1.tgz", + "integrity": "sha512-Rx4rHS0pVuJn5pJOqaqcZR4XSgeF9G/pO/79t+4r7380tXFJdzImFnxMU19f83wjSrmKHq6myrM10pFHTGzkUA==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-regex": "^7.10.1", + "regexpu-core": "^4.7.0" + } + }, + "@babel/helper-define-map": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz", + "integrity": "sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz", + "integrity": "sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg==", + "dev": true, + "requires": { + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-function-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz", + "integrity": "sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz", + "integrity": "sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz", + "integrity": "sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz", + "integrity": "sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-imports": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz", + "integrity": "sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-module-transforms": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.10.1.tgz", + "integrity": "sha512-RLHRCAzyJe7Q7sF4oy2cB+kRnU4wDZY/H2xJFGof+M+SJEGhZsb+GFj5j1AD8NiSaVBJ+Pf0/WObiXu/zxWpFg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz", + "integrity": "sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz", + "integrity": "sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.10.1.tgz", + "integrity": "sha512-7isHr19RsIJWWLLFn21ubFt223PjQyg1HY7CZEMRr820HttHPpVvrsIN3bUOo44DEfFV4kBXO7Abbn9KTUZV7g==", + "dev": true, + "requires": { + "lodash": "^4.17.13" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz", + "integrity": "sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-wrap-function": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-replace-supers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.10.1.tgz", + "integrity": "sha512-SOwJzEfpuQwInzzQJGjGaiG578UYmyi2Xw668klPWV5n07B73S0a9btjLk/52Mlcxa+5AdIYqws1KyXRfMoB7A==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-simple-access": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.10.1.tgz", + "integrity": "sha512-VSWpWzRzn9VtgMJBIWTZ+GP107kZdQ4YplJlCmIrjoLVSi/0upixezHCDG8kpPVTBJpKfxTH01wDhh+jS2zKbw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.10.1.tgz", + "integrity": "sha512-UQ1LVBPrYdbchNhLwj6fetj46BcFwfS4NllJo/1aJsT+1dLTEnXJL0qHqtY7gPzF8S2fXBJamf1biAXV3X077g==", + "dev": true, + "requires": { + "@babel/types": "^7.10.1" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz", + "integrity": "sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw==", + "dev": true + }, + "@babel/helper-wrap-function": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.10.1.tgz", + "integrity": "sha512-C0MzRGteVDn+H32/ZgbAv5r56f2o1fZSA/rj/TYo8JEJNHg+9BdSmKBUND0shxWRztWhjlT2cvHYuynpPsVJwQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/helpers": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.10.1.tgz", + "integrity": "sha512-muQNHF+IdU6wGgkaJyhhEmI54MOZBKsFfsXFhboz1ybwJ1Kl7IHlbm2a++4jwrmY5UYsgitt5lfqo1wMFcHmyw==", + "dev": true, + "requires": { + "@babel/template": "^7.10.1", + "@babel/traverse": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/highlight": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.10.1.tgz", + "integrity": "sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.10.2.tgz", + "integrity": "sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz", + "integrity": "sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1", + "@babel/plugin-syntax-async-generators": "^7.8.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.1.tgz", + "integrity": "sha512-sqdGWgoXlnOdgMXU+9MbhzwFRgxVLeiGBqTrnuS7LC2IBU31wSsESbTUreT2O418obpfPdGUR2GbEufZF1bpqw==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-proposal-dynamic-import": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.1.tgz", + "integrity": "sha512-Cpc2yUVHTEGPlmiQzXj026kqwjEQAD9I4ZC16uzdbgWgitg/UHKHLffKNCQZ5+y8jpIZPJcKcwsr2HwPh+w3XA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.1.tgz", + "integrity": "sha512-m8r5BmV+ZLpWPtMY2mOKN7wre6HIO4gfIiV+eOmsnZABNenrt/kzYBwrh+KOfgumSWpnlGs5F70J8afYMSJMBg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-json-strings": "^7.8.0" + } + }, + "@babel/plugin-proposal-nullish-coalescing-operator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.1.tgz", + "integrity": "sha512-56cI/uHYgL2C8HVuHOuvVowihhX0sxb3nnfVRzUeVHTWmRHTZrKuAh/OBIMggGU/S1g/1D2CRCXqP+3u7vX7iA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0" + } + }, + "@babel/plugin-proposal-numeric-separator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.1.tgz", + "integrity": "sha512-jjfym4N9HtCiNfyyLAVD8WqPYeHUrw4ihxuAynWj6zzp2gf9Ey2f7ImhFm6ikB3CLf5Z/zmcJDri6B4+9j9RsA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-numeric-separator": "^7.10.1" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz", + "integrity": "sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-transform-parameters": "^7.10.1" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.1.tgz", + "integrity": "sha512-VqExgeE62YBqI3ogkGoOJp1R6u12DFZjqwJhqtKc2o5m1YTUuUWnos7bZQFBhwkxIFpWYJ7uB75U7VAPPiKETA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0" + } + }, + "@babel/plugin-proposal-optional-chaining": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz", + "integrity": "sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-syntax-optional-chaining": "^7.8.0" + } + }, + "@babel/plugin-proposal-private-methods": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.1.tgz", + "integrity": "sha512-RZecFFJjDiQ2z6maFprLgrdnm0OzoC23Mx89xf1CcEsxmHuzuXOdniEuI+S3v7vjQG4F5sa6YtUp+19sZuSxHg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.1.tgz", + "integrity": "sha512-JjfngYRvwmPwmnbRZyNiPFI8zxCZb8euzbCG/LxyKdeTb59tVciKo9GK9bi6JYKInk1H11Dq9j/zRqIH4KigfQ==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.8.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz", + "integrity": "sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-class-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.1.tgz", + "integrity": "sha512-Gf2Yx/iRs1JREDtVZ56OrjjgFHCaldpTnuy9BHla10qyVT3YkIIGEtoDWhyop0ksu1GvNjHIoYRBqm3zoR1jyQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-dynamic-import": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz", + "integrity": "sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz", + "integrity": "sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-nullish-coalescing-operator": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz", + "integrity": "sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-numeric-separator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.1.tgz", + "integrity": "sha512-uTd0OsHrpe3tH5gRPTxG8Voh99/WCU78vIm5NMRYPAqC8lR4vajt6KkCAknCHrx24vkPdd/05yfdGSB4EIY2mg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz", + "integrity": "sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz", + "integrity": "sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-optional-chaining": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz", + "integrity": "sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.8.0" + } + }, + "@babel/plugin-syntax-top-level-await": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.1.tgz", + "integrity": "sha512-hgA5RYkmZm8FTFT3yu2N9Bx7yVVOKYT6yEdXXo6j2JTm0wNxgqaGeQVaSHRjhfnQbX91DtjFB6McRFSlcJH3xQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.1.tgz", + "integrity": "sha512-6AZHgFJKP3DJX0eCNJj01RpytUa3SOGawIxweHkNX2L6PYikOZmoh5B0d7hIHaIgveMjX990IAa/xK7jRTN8OA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.1.tgz", + "integrity": "sha512-XCgYjJ8TY2slj6SReBUyamJn3k2JLUIiiR5b6t1mNCMSvv7yx+jJpaewakikp0uWFQSF7ChPPoe3dHmXLpISkg==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-remap-async-to-generator": "^7.10.1" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.1.tgz", + "integrity": "sha512-B7K15Xp8lv0sOJrdVAoukKlxP9N59HS48V1J3U/JGj+Ad+MHq+am6xJVs85AgXrQn4LV8vaYFOB+pr/yIuzW8Q==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.10.1.tgz", + "integrity": "sha512-8bpWG6TtF5akdhIm/uWTyjHqENpy13Fx8chg7pFH875aNLwX8JxIxqm08gmAT+Whe6AOmaTeLPe7dpLbXt+xUw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "lodash": "^4.17.13" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz", + "integrity": "sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-define-map": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-optimise-call-expression": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz", + "integrity": "sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.1.tgz", + "integrity": "sha512-V/nUc4yGWG71OhaTH705pU8ZSdM6c1KmmLP8ys59oOYbT7RpMYAR3MsVOt6OHL0WzG7BlTU076va9fjJyYzJMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.1.tgz", + "integrity": "sha512-19VIMsD1dp02RvduFUmfzj8uknaO3uiHHF0s3E1OHnVsNj8oge8EQ5RzHRbJjGSetRnkEuBYO7TG1M5kKjGLOA==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.1.tgz", + "integrity": "sha512-wIEpkX4QvX8Mo9W6XF3EdGttrIPZWozHfEaDTU0WJD/TDnXMvdDh30mzUl/9qWhnf7naicYartcEfUghTCSNpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.1.tgz", + "integrity": "sha512-lr/przdAbpEA2BUzRvjXdEDLrArGRRPwbaF9rvayuHRvdQ7lUTTkZnhZrJ4LE2jvgMRFF4f0YuPQ20vhiPYxtA==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.1.tgz", + "integrity": "sha512-US8KCuxfQcn0LwSCMWMma8M2R5mAjJGsmoCBVwlMygvmDUMkTCykc84IqN1M7t+agSfOmLYTInLCHJM+RUoz+w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.1.tgz", + "integrity": "sha512-//bsKsKFBJfGd65qSNNh1exBy5Y9gD9ZN+DvrJ8f7HXr4avE5POW6zB7Rj6VnqHV33+0vXWUwJT0wSHubiAQkw==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.1.tgz", + "integrity": "sha512-qi0+5qgevz1NHLZroObRm5A+8JJtibb7vdcPQF1KQE12+Y/xxl8coJ+TpPW9iRq+Mhw/NKLjm+5SHtAHCC7lAw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.1.tgz", + "integrity": "sha512-UmaWhDokOFT2GcgU6MkHC11i0NQcL63iqeufXWfRy6pUOGYeCGEKhvfFO6Vz70UfYJYHwveg62GS83Rvpxn+NA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.1.tgz", + "integrity": "sha512-31+hnWSFRI4/ACFr1qkboBbrTxoBIzj7qA69qlq8HY8p7+YCzkCT6/TvQ1a4B0z27VeWtAeJd6pr5G04dc1iHw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.1.tgz", + "integrity": "sha512-AQG4fc3KOah0vdITwt7Gi6hD9BtQP/8bhem7OjbaMoRNCH5Djx42O2vYMfau7QnAzQCa+RJnhJBmFFMGpQEzrg==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-simple-access": "^7.10.1", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz", + "integrity": "sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.10.1", + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "babel-plugin-dynamic-import-node": "^2.3.3" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.1.tgz", + "integrity": "sha512-EIuiRNMd6GB6ulcYlETnYYfgv4AxqrswghmBRQbWLHZxN4s7mupxzglnHqk9ZiUpDI4eRWewedJJNj67PWOXKA==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.8.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz", + "integrity": "sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.8.3" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.1.tgz", + "integrity": "sha512-MBlzPc1nJvbmO9rPr1fQwXOM2iGut+JC92ku6PbiJMMK7SnQc1rytgpopveE3Evn47gzvGYeCdgfCDbZo0ecUw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.1.tgz", + "integrity": "sha512-WnnStUDN5GL+wGQrJylrnnVlFhFmeArINIR9gjhSeYyvroGhBrSAXYg/RHsnfzmsa+onJrTJrEClPzgNmmQ4Gw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-replace-supers": "^7.10.1" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.1.tgz", + "integrity": "sha512-tJ1T0n6g4dXMsL45YsSzzSDZCxiHXAQp/qHrucOq5gEHncTA3xDxnd5+sZcoQp+N1ZbieAaB8r/VUCG0gqseOg==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.1.tgz", + "integrity": "sha512-Kr6+mgag8auNrgEpbfIWzdXYOvqDHZOF0+Bx2xh4H2EDNwcbRb9lY6nkZg8oSjsX+DH9Ebxm9hOqtKW+gRDeNA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz", + "integrity": "sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.2" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.1.tgz", + "integrity": "sha512-qN1OMoE2nuqSPmpTqEM7OvJ1FkMEV+BjVeZZm9V9mq/x1JLKQ4pcv8riZJMNN3u2AUGl0ouOMjRr2siecvHqUQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-runtime": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.1.tgz", + "integrity": "sha512-4w2tcglDVEwXJ5qxsY++DgWQdNJcCCsPxfT34wCUwIf2E7dI7pMpH8JczkMBbgBTNzBX62SZlNJ9H+De6Zebaw==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "resolve": "^1.8.1", + "semver": "^5.5.1" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.1.tgz", + "integrity": "sha512-AR0E/lZMfLstScFwztApGeyTHJ5u3JUKMjneqRItWeEqDdHWZwAOKycvQNCasCK/3r5YXsuNG25funcJDu7Y2g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.10.1.tgz", + "integrity": "sha512-8wTPym6edIrClW8FI2IoaePB91ETOtg36dOkj3bYcNe7aDMN2FXEoUa+WrmPc4xa1u2PQK46fUX2aCb+zo9rfw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.1.tgz", + "integrity": "sha512-j17ojftKjrL7ufX8ajKvwRilwqTok4q+BjkknmQw9VNHnItTyMP5anPFzxFJdCQs7clLcWpCV3ma+6qZWLnGMA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/helper-regex": "^7.10.1" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz", + "integrity": "sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.1.tgz", + "integrity": "sha512-qX8KZcmbvA23zDi+lk9s6hC1FM7jgLHYIjuLgULgc8QtYnmB3tAVIYkNoKRQ75qWBeyzcoMoK8ZQmogGtC/w0g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-unicode-escapes": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.1.tgz", + "integrity": "sha512-zZ0Poh/yy1d4jeDWpx/mNwbKJVwUYJX73q+gyh4bwtG0/iUlzdEu0sLMda8yuDFS6LBQlT/ST1SJAR6zYwXWgw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.1.tgz", + "integrity": "sha512-Y/2a2W299k0VIUdbqYm9X2qS6fE0CUBhhiPpimK6byy7OJ/kORLlIX+J6UrjgNu5awvs62k+6RSslxhcvVw2Tw==", + "dev": true, + "requires": { + "@babel/helper-create-regexp-features-plugin": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1" + } + }, + "@babel/preset-env": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.10.2.tgz", + "integrity": "sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA==", + "dev": true, + "requires": { + "@babel/compat-data": "^7.10.1", + "@babel/helper-compilation-targets": "^7.10.2", + "@babel/helper-module-imports": "^7.10.1", + "@babel/helper-plugin-utils": "^7.10.1", + "@babel/plugin-proposal-async-generator-functions": "^7.10.1", + "@babel/plugin-proposal-class-properties": "^7.10.1", + "@babel/plugin-proposal-dynamic-import": "^7.10.1", + "@babel/plugin-proposal-json-strings": "^7.10.1", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.10.1", + "@babel/plugin-proposal-numeric-separator": "^7.10.1", + "@babel/plugin-proposal-object-rest-spread": "^7.10.1", + "@babel/plugin-proposal-optional-catch-binding": "^7.10.1", + "@babel/plugin-proposal-optional-chaining": "^7.10.1", + "@babel/plugin-proposal-private-methods": "^7.10.1", + "@babel/plugin-proposal-unicode-property-regex": "^7.10.1", + "@babel/plugin-syntax-async-generators": "^7.8.0", + "@babel/plugin-syntax-class-properties": "^7.10.1", + "@babel/plugin-syntax-dynamic-import": "^7.8.0", + "@babel/plugin-syntax-json-strings": "^7.8.0", + "@babel/plugin-syntax-nullish-coalescing-operator": "^7.8.0", + "@babel/plugin-syntax-numeric-separator": "^7.10.1", + "@babel/plugin-syntax-object-rest-spread": "^7.8.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.8.0", + "@babel/plugin-syntax-optional-chaining": "^7.8.0", + "@babel/plugin-syntax-top-level-await": "^7.10.1", + "@babel/plugin-transform-arrow-functions": "^7.10.1", + "@babel/plugin-transform-async-to-generator": "^7.10.1", + "@babel/plugin-transform-block-scoped-functions": "^7.10.1", + "@babel/plugin-transform-block-scoping": "^7.10.1", + "@babel/plugin-transform-classes": "^7.10.1", + "@babel/plugin-transform-computed-properties": "^7.10.1", + "@babel/plugin-transform-destructuring": "^7.10.1", + "@babel/plugin-transform-dotall-regex": "^7.10.1", + "@babel/plugin-transform-duplicate-keys": "^7.10.1", + "@babel/plugin-transform-exponentiation-operator": "^7.10.1", + "@babel/plugin-transform-for-of": "^7.10.1", + "@babel/plugin-transform-function-name": "^7.10.1", + "@babel/plugin-transform-literals": "^7.10.1", + "@babel/plugin-transform-member-expression-literals": "^7.10.1", + "@babel/plugin-transform-modules-amd": "^7.10.1", + "@babel/plugin-transform-modules-commonjs": "^7.10.1", + "@babel/plugin-transform-modules-systemjs": "^7.10.1", + "@babel/plugin-transform-modules-umd": "^7.10.1", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.8.3", + "@babel/plugin-transform-new-target": "^7.10.1", + "@babel/plugin-transform-object-super": "^7.10.1", + "@babel/plugin-transform-parameters": "^7.10.1", + "@babel/plugin-transform-property-literals": "^7.10.1", + "@babel/plugin-transform-regenerator": "^7.10.1", + "@babel/plugin-transform-reserved-words": "^7.10.1", + "@babel/plugin-transform-shorthand-properties": "^7.10.1", + "@babel/plugin-transform-spread": "^7.10.1", + "@babel/plugin-transform-sticky-regex": "^7.10.1", + "@babel/plugin-transform-template-literals": "^7.10.1", + "@babel/plugin-transform-typeof-symbol": "^7.10.1", + "@babel/plugin-transform-unicode-escapes": "^7.10.1", + "@babel/plugin-transform-unicode-regex": "^7.10.1", + "@babel/preset-modules": "^0.1.3", + "@babel/types": "^7.10.2", + "browserslist": "^4.12.0", + "core-js-compat": "^3.6.2", + "invariant": "^2.2.2", + "levenary": "^1.1.1", + "semver": "^5.5.0" + } + }, + "@babel/preset-modules": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@babel/preset-modules/-/preset-modules-0.1.3.tgz", + "integrity": "sha512-Ra3JXOHBq2xd56xSF7lMKXdjBn3T772Y1Wet3yWnkDly9zHvJki029tAFzvAAK5cf4YV3yoxuP61crYRol6SVg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "esutils": "^2.0.2" + } + }, + "@babel/runtime": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.10.2.tgz", + "integrity": "sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/template": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.10.1.tgz", + "integrity": "sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1" + } + }, + "@babel/traverse": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.10.1.tgz", + "integrity": "sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.10.1", + "@babel/generator": "^7.10.1", + "@babel/helper-function-name": "^7.10.1", + "@babel/helper-split-export-declaration": "^7.10.1", + "@babel/parser": "^7.10.1", + "@babel/types": "^7.10.1", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.13" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.10.2", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.10.2.tgz", + "integrity": "sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.10.1", + "lodash": "^4.17.13", + "to-fast-properties": "^2.0.0" + } + }, + "@fortawesome/fontawesome-free": { + "version": "5.13.0", + "resolved": "https://registry.npmjs.org/@fortawesome/fontawesome-free/-/fontawesome-free-5.13.0.tgz", + "integrity": "sha512-xKOeQEl5O47GPZYIMToj6uuA2syyFlq9EMSl2ui0uytjY9xbe8XS0pexNWmxrdcCyNGyDmLyYw5FtKsalBUeOg==" + }, + "@mrmlnc/readdir-enhanced": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/@mrmlnc/readdir-enhanced/-/readdir-enhanced-2.2.1.tgz", + "integrity": "sha512-bPHp6Ji8b41szTOcaP63VlnbbO5Ny6dwAATtY6JTjh5N2OLrb5Qk/Th5cRkRQhkWCt+EJsYrNB0MiL+Gpn6e3g==", + "dev": true, + "requires": { + "call-me-maybe": "^1.0.1", + "glob-to-regexp": "^0.3.0" + } + }, + "@nodelib/fs.stat": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-1.1.3.tgz", + "integrity": "sha512-shAmDyaQC4H92APFoIaVDHCx5bStIocgvbwQyxPRrbUY20V1EYTbSDchWbuwlMG3V17cprZhA6+78JfB+3DTPw==", + "dev": true + }, + "@popperjs/core": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.4.2.tgz", + "integrity": "sha512-JlGTGRYHC2QK+DDbePyXdBdooxFq2+noLfWpRqJtkxcb/oYWzOF0kcbfvvbWrwevCC1l6hLUg1wHYT+ona5BWQ==" + }, + "@types/glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/@types/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-VgNIkxK+j7Nz5P7jvUZlRvhuPSmsEfS03b0alKcq5V/STUKAa3Plemsn5mrQUO7am6OErJ4rhGEGJbACclrtRA==", + "dev": true, + "requires": { + "@types/minimatch": "*", + "@types/node": "*" + } + }, + "@types/json-schema": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.5.tgz", + "integrity": "sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ==", + "dev": true + }, + "@types/minimatch": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz", + "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==", + "dev": true + }, + "@types/node": { + "version": "14.0.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.13.tgz", + "integrity": "sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA==", + "dev": true + }, + "@types/q": { + "version": "1.5.4", + "resolved": "https://registry.npmjs.org/@types/q/-/q-1.5.4.tgz", + "integrity": "sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug==", + "dev": true + }, + "@vue/component-compiler-utils": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/@vue/component-compiler-utils/-/component-compiler-utils-3.1.2.tgz", + "integrity": "sha512-QLq9z8m79mCinpaEeSURhnNCN6djxpHw0lpP/bodMlt5kALfONpryMthvnrQOlTcIKoF+VoPi+lPHUYeDFPXug==", + "dev": true, + "requires": { + "consolidate": "^0.15.1", + "hash-sum": "^1.0.2", + "lru-cache": "^4.1.2", + "merge-source-map": "^1.1.0", + "postcss": "^7.0.14", + "postcss-selector-parser": "^6.0.2", + "prettier": "^1.18.2", + "source-map": "~0.6.1", + "vue-template-es2015-compiler": "^1.9.0" + }, + "dependencies": { + "lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "requires": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", + "dev": true + } + } + }, + "@webassemblyjs/ast": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.9.0.tgz", + "integrity": "sha512-C6wW5L+b7ogSDVqymbkkvuW9kruN//YisMED04xzeBBqjHa2FYnmvOlS6Xj68xWQRgWvI9cIglsjFowH/RJyEA==", + "dev": true, + "requires": { + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0" + } + }, + "@webassemblyjs/floating-point-hex-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.9.0.tgz", + "integrity": "sha512-TG5qcFsS8QB4g4MhrxK5TqfdNe7Ey/7YL/xN+36rRjl/BlGE/NcBvJcqsRgCP6Z92mRE+7N50pRIi8SmKUbcQA==", + "dev": true + }, + "@webassemblyjs/helper-api-error": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.9.0.tgz", + "integrity": "sha512-NcMLjoFMXpsASZFxJ5h2HZRcEhDkvnNFOAKneP5RbKRzaWJN36NC4jqQHKwStIhGXu5mUWlUUk7ygdtrO8lbmw==", + "dev": true + }, + "@webassemblyjs/helper-buffer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.9.0.tgz", + "integrity": "sha512-qZol43oqhq6yBPx7YM3m9Bv7WMV9Eevj6kMi6InKOuZxhw+q9hOkvq5e/PpKSiLfyetpaBnogSbNCfBwyB00CA==", + "dev": true + }, + "@webassemblyjs/helper-code-frame": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.9.0.tgz", + "integrity": "sha512-ERCYdJBkD9Vu4vtjUYe8LZruWuNIToYq/ME22igL+2vj2dQ2OOujIZr3MEFvfEaqKoVqpsFKAGsRdBSBjrIvZA==", + "dev": true, + "requires": { + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/helper-fsm": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.9.0.tgz", + "integrity": "sha512-OPRowhGbshCb5PxJ8LocpdX9Kl0uB4XsAjl6jH/dWKlk/mzsANvhwbiULsaiqT5GZGT9qinTICdj6PLuM5gslw==", + "dev": true + }, + "@webassemblyjs/helper-module-context": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.9.0.tgz", + "integrity": "sha512-MJCW8iGC08tMk2enck1aPW+BE5Cw8/7ph/VGZxwyvGbJwjktKkDK7vy7gAmMDx88D7mhDTCNKAW5tED+gZ0W8g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0" + } + }, + "@webassemblyjs/helper-wasm-bytecode": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.9.0.tgz", + "integrity": "sha512-R7FStIzyNcd7xKxCZH5lE0Bqy+hGTwS3LJjuv1ZVxd9O7eHCedSdrId/hMOd20I+v8wDXEn+bjfKDLzTepoaUw==", + "dev": true + }, + "@webassemblyjs/helper-wasm-section": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.9.0.tgz", + "integrity": "sha512-XnMB8l3ek4tvrKUUku+IVaXNHz2YsJyOOmz+MMkZvh8h1uSJpSen6vYnw3IoQ7WwEuAhL8Efjms1ZWjqh2agvw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0" + } + }, + "@webassemblyjs/ieee754": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.9.0.tgz", + "integrity": "sha512-dcX8JuYU/gvymzIHc9DgxTzUUTLexWwt8uCTWP3otys596io0L5aW02Gb1RjYpx2+0Jus1h4ZFqjla7umFniTg==", + "dev": true, + "requires": { + "@xtuc/ieee754": "^1.2.0" + } + }, + "@webassemblyjs/leb128": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.9.0.tgz", + "integrity": "sha512-ENVzM5VwV1ojs9jam6vPys97B/S65YQtv/aanqnU7D8aSoHFX8GyhGg0CMfyKNIHBuAVjy3tlzd5QMMINa7wpw==", + "dev": true, + "requires": { + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/utf8": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.9.0.tgz", + "integrity": "sha512-GZbQlWtopBTP0u7cHrEx+73yZKrQoBMpwkGEIqlacljhXCkVM1kMQge/Mf+csMJAjEdSwhOyLAS0AoR3AG5P8w==", + "dev": true + }, + "@webassemblyjs/wasm-edit": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.9.0.tgz", + "integrity": "sha512-FgHzBm80uwz5M8WKnMTn6j/sVbqilPdQXTWraSjBwFXSYGirpkSWE2R9Qvz9tNiTKQvoKILpCuTjBKzOIm0nxw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/helper-wasm-section": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-opt": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "@webassemblyjs/wast-printer": "1.9.0" + } + }, + "@webassemblyjs/wasm-gen": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.9.0.tgz", + "integrity": "sha512-cPE3o44YzOOHvlsb4+E9qSqjc9Qf9Na1OO/BHFy4OI91XDE14MjFN4lTMezzaIWdPqHnsTodGGNP+iRSYfGkjA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wasm-opt": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.9.0.tgz", + "integrity": "sha512-Qkjgm6Anhm+OMbIL0iokO7meajkzQD71ioelnfPEj6r4eOFuqm4YC3VBPqXjFyyNwowzbMD+hizmprP/Fwkl2A==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-buffer": "1.9.0", + "@webassemblyjs/wasm-gen": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0" + } + }, + "@webassemblyjs/wasm-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.9.0.tgz", + "integrity": "sha512-9+wkMowR2AmdSWQzsPEjFU7njh8HTO5MqO8vjwEHuM+AMHioNqSBONRdr0NQQ3dVQrzp0s8lTcYqzUdb7YgELA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-wasm-bytecode": "1.9.0", + "@webassemblyjs/ieee754": "1.9.0", + "@webassemblyjs/leb128": "1.9.0", + "@webassemblyjs/utf8": "1.9.0" + } + }, + "@webassemblyjs/wast-parser": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.9.0.tgz", + "integrity": "sha512-qsqSAP3QQ3LyZjNC/0jBJ/ToSxfYJ8kYyuiGvtn/8MK89VrNEfwj7BPQzJVHi0jGTRK2dGdJ5PRqhtjzoww+bw==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/floating-point-hex-parser": "1.9.0", + "@webassemblyjs/helper-api-error": "1.9.0", + "@webassemblyjs/helper-code-frame": "1.9.0", + "@webassemblyjs/helper-fsm": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@webassemblyjs/wast-printer": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.9.0.tgz", + "integrity": "sha512-2J0nE95rHXHyQ24cWjMKJ1tqB/ds8z/cyeOZxJhcb+rW+SQASVjuznUSmdz5GpVJTzU8JkhYut0D3siFDD6wsA==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/wast-parser": "1.9.0", + "@xtuc/long": "4.2.2" + } + }, + "@xtuc/ieee754": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", + "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", + "dev": true + }, + "@xtuc/long": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", + "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", + "dev": true + }, + "accepts": { + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", + "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", + "dev": true, + "requires": { + "mime-types": "~2.1.24", + "negotiator": "0.6.2" + } + }, + "acorn": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.4.1.tgz", + "integrity": "sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA==", + "dev": true + }, + "acorn-walk": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-7.1.1.tgz", + "integrity": "sha512-wdlPY2tm/9XBr7QkKlq0WQVgiuGTX6YWPyRyBviSoScBuLfTVQhvwg6wJ369GJ/1nPfTLMfnrFIfjqVg6d+jQQ==", + "dev": true + }, + "adjust-sourcemap-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/adjust-sourcemap-loader/-/adjust-sourcemap-loader-2.0.0.tgz", + "integrity": "sha512-4hFsTsn58+YjrU9qKzML2JSSDqKvN8mUGQ0nNIrfPi8hmIONT4L3uUaT6MKdMsZ9AjsU6D2xDkZxCkbQPxChrA==", + "dev": true, + "requires": { + "assert": "1.4.1", + "camelcase": "5.0.0", + "loader-utils": "1.2.3", + "object-path": "0.11.4", + "regex-parser": "2.2.10" + }, + "dependencies": { + "assert": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.4.1.tgz", + "integrity": "sha1-mZEtWRg2tab1s0XA8H7vwI/GXZE=", + "dev": true, + "requires": { + "util": "0.10.3" + } + }, + "camelcase": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.0.0.tgz", + "integrity": "sha512-faqwZqnWxbxn+F1d399ygeamQNy3lPp/H9H6rNrqYh4FSVCtcY+3cub1MxA8o9mDd55mM8Aghuu/kuyYA6VTsA==", + "dev": true + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "aggregate-error": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.0.1.tgz", + "integrity": "sha512-quoaXsZ9/BLNae5yiNoUz+Nhkwz83GhWwtYFglcjEQB2NDHCIpApbqXxIFnm4Pq/Nvhrsq5sYJFyohrrxnTGAA==", + "dev": true, + "requires": { + "clean-stack": "^2.0.0", + "indent-string": "^4.0.0" + } + }, + "ajv": { + "version": "6.12.2", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.2.tgz", + "integrity": "sha512-k+V+hzjm5q/Mr8ef/1Y9goCmlsK4I6Sm74teeyGvFk1XrOsbsKLjEdrvny42CZ+a8sXbk8KWpY/bDwS+FLL2UQ==", + "dev": true, + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ajv-errors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", + "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", + "dev": true + }, + "ajv-keywords": { + "version": "3.4.1", + "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", + "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", + "dev": true + }, + "alphanum-sort": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/alphanum-sort/-/alphanum-sort-1.0.2.tgz", + "integrity": "sha1-l6ERlkmyEa0zaR2fn0hqjsn74KM=", + "dev": true + }, + "ansi-colors": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.4.tgz", + "integrity": "sha512-hHUXGagefjN2iRrID63xckIvotOXOojhQKWIPUZ4mNUZ9nLZW+7FMNoE1lOkEhNWYsx/7ysGIuJYCiMAA9FnrA==", + "dev": true + }, + "ansi-html": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ansi-html/-/ansi-html-0.0.7.tgz", + "integrity": "sha1-gTWEAhliqenm/QOflA0S9WynhZ4=", + "dev": true + }, + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "aproba": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", + "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", + "dev": true + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "arity-n": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/arity-n/-/arity-n-1.0.4.tgz", + "integrity": "sha1-2edrEXM+CFacCEeuezmyhgswt0U=", + "dev": true + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true + }, + "array-flatten": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-2.1.2.tgz", + "integrity": "sha512-hNfzcOV8W4NdualtqBFPyVO+54DSJuZGY9qT4pRroB6S9e3iiido2ISIC5h9R2sPJ8H3FHCIiEnsv1lPXO3KtQ==", + "dev": true + }, + "array-union": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/array-union/-/array-union-1.0.2.tgz", + "integrity": "sha1-mjRBDk9OPaI96jdb5b5w8kd47Dk=", + "dev": true, + "requires": { + "array-uniq": "^1.0.1" + } + }, + "array-uniq": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/array-uniq/-/array-uniq-1.0.3.tgz", + "integrity": "sha1-r2rId6Jcx/dOBYiUdThY39sk/bY=", + "dev": true + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true + }, + "arrify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/arrify/-/arrify-1.0.1.tgz", + "integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=", + "dev": true + }, + "asn1.js": { + "version": "4.10.1", + "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", + "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "assert": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", + "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", + "dev": true, + "requires": { + "object-assign": "^4.1.1", + "util": "0.10.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", + "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", + "dev": true + }, + "util": { + "version": "0.10.3", + "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", + "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", + "dev": true, + "requires": { + "inherits": "2.0.1" + } + } + } + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true + }, + "ast-types": { + "version": "0.9.6", + "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.9.6.tgz", + "integrity": "sha1-ECyenpAF0+fjgpvwxPok7oYu6bk=", + "dev": true + }, + "async": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/async/-/async-2.6.3.tgz", + "integrity": "sha512-zflvls11DCy+dQWzTW2dzuilv8Z5X/pjfmZOWba6TNIVDm+2UDaJmXSOXlasHKfNBs8oo3M0aT50fDEWfKZjXg==", + "dev": true, + "requires": { + "lodash": "^4.17.14" + } + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true + }, + "async-limiter": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==", + "dev": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true + }, + "autoprefixer": { + "version": "9.8.0", + "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-9.8.0.tgz", + "integrity": "sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A==", + "dev": true, + "requires": { + "browserslist": "^4.12.0", + "caniuse-lite": "^1.0.30001061", + "chalk": "^2.4.2", + "normalize-range": "^0.1.2", + "num2fraction": "^1.2.2", + "postcss": "^7.0.30", + "postcss-value-parser": "^4.1.0" + } + }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz", + "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==", + "dev": true, + "requires": { + "follow-redirects": "1.5.10" + } + }, + "babel-code-frame": { + "version": "6.26.0", + "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", + "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "esutils": "^2.0.2", + "js-tokens": "^3.0.2" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "js-tokens": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", + "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=", + "dev": true + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "babel-loader": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-8.1.0.tgz", + "integrity": "sha512-7q7nC1tYOrqvUrN3LQK4GwSk/TQorZSOlO9C+RZDZpODgyN4ZlCqE5q9cDsyWOliN+aU9B4JX01xK9eJXowJLw==", + "dev": true, + "requires": { + "find-cache-dir": "^2.1.0", + "loader-utils": "^1.4.0", + "mkdirp": "^0.5.3", + "pify": "^4.0.1", + "schema-utils": "^2.6.5" + } + }, + "babel-merge": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/babel-merge/-/babel-merge-2.0.1.tgz", + "integrity": "sha512-puTQQxuzS+0JlMyVdfsTVaCgzqjBXKPMv7oUANpYcHFY+7IptWZ4PZDYX+qBxrRMtrriuBA44LkKpS99EJzqVA==", + "dev": true, + "requires": { + "@babel/core": "^7.0.0-beta.49", + "deepmerge": "^2.1.0", + "object.omit": "^3.0.0" + } + }, + "babel-plugin-dynamic-import-node": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", + "integrity": "sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ==", + "dev": true, + "requires": { + "object.assign": "^4.1.0" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "base64-js": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", + "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", + "dev": true + }, + "batch": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/batch/-/batch-0.6.1.tgz", + "integrity": "sha1-3DQxT05nkxgJP8dgJyUl+UvyXBY=", + "dev": true + }, + "bfj": { + "version": "6.1.2", + "resolved": "https://registry.npmjs.org/bfj/-/bfj-6.1.2.tgz", + "integrity": "sha512-BmBJa4Lip6BPRINSZ0BPEIfB1wUY/9rwbwvIHQA1KjX9om29B6id0wnWXq7m3bn5JrUVjeOTnVuhPT1FiHwPGw==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "check-types": "^8.0.3", + "hoopy": "^0.1.4", + "tryer": "^1.0.1" + } + }, + "big.js": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", + "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", + "dev": true + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true + }, + "bindings": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", + "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", + "dev": true, + "optional": true, + "requires": { + "file-uri-to-path": "1.0.0" + } + }, + "bluebird": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", + "integrity": "sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==", + "dev": true + }, + "bn.js": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.1.2.tgz", + "integrity": "sha512-40rZaf3bUNKTVYu9sIeeEGOg7g14Yvnj9kH7b50EiwX0Q7A6umbvfI5tvHaOERH0XigqKkfLkFQxzb4e6CIXnA==", + "dev": true + }, + "body-parser": { + "version": "1.19.0", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", + "integrity": "sha512-dhEPs72UPbDnAQJ9ZKMNTP6ptJaionhP5cBb541nXPlW60Jepo9RV/a4fX4XWW9CuFNK22krhrj1+rgzifNCsw==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "content-type": "~1.0.4", + "debug": "2.6.9", + "depd": "~1.1.2", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "on-finished": "~2.3.0", + "qs": "6.7.0", + "raw-body": "2.4.0", + "type-is": "~1.6.17" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "bonjour": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/bonjour/-/bonjour-3.5.0.tgz", + "integrity": "sha1-jokKGD2O6aI5OzhExpGkK897yfU=", + "dev": true, + "requires": { + "array-flatten": "^2.1.0", + "deep-equal": "^1.0.1", + "dns-equal": "^1.0.0", + "dns-txt": "^2.0.2", + "multicast-dns": "^6.0.1", + "multicast-dns-service-types": "^1.1.0" + } + }, + "boolbase": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz", + "integrity": "sha1-aN/1++YMUes3cl6p4+0xDcwed24=", + "dev": true + }, + "bootstrap": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-4.5.0.tgz", + "integrity": "sha512-Z93QoXvodoVslA+PWNdk23Hze4RBYIkpb5h8I2HY2Tu2h7A0LpAgLcyrhrSUyo2/Oxm2l1fRZPs1e5hnxnliXA==" + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "brorand": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", + "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", + "dev": true + }, + "browserify-aes": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", + "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", + "dev": true, + "requires": { + "buffer-xor": "^1.0.3", + "cipher-base": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.3", + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "browserify-cipher": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", + "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", + "dev": true, + "requires": { + "browserify-aes": "^1.0.4", + "browserify-des": "^1.0.0", + "evp_bytestokey": "^1.0.0" + } + }, + "browserify-des": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", + "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "des.js": "^1.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "browserify-rsa": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", + "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "randombytes": "^2.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "browserify-sign": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.2.0.tgz", + "integrity": "sha512-hEZC1KEeYuoHRqhGhTy6gWrpJA3ZDjFWv0DE61643ZnOXAKJb3u7yWcrU0mMc9SwAqK1n7myPGndkp0dFG7NFA==", + "dev": true, + "requires": { + "bn.js": "^5.1.1", + "browserify-rsa": "^4.0.1", + "create-hash": "^1.2.0", + "create-hmac": "^1.1.7", + "elliptic": "^6.5.2", + "inherits": "^2.0.4", + "parse-asn1": "^5.1.5", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "browserify-zlib": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", + "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", + "dev": true, + "requires": { + "pako": "~1.0.5" + } + }, + "browserslist": { + "version": "4.12.0", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.12.0.tgz", + "integrity": "sha512-UH2GkcEDSI0k/lRkuDSzFl9ZZ87skSy9w2XAn1MsZnL+4c4rqbBd3e82UWHbYDpztABrPBhZsTEeuxVfHppqDg==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30001043", + "electron-to-chromium": "^1.3.413", + "node-releases": "^1.1.53", + "pkg-up": "^2.0.0" + } + }, + "buffer": { + "version": "4.9.2", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.2.tgz", + "integrity": "sha512-xq+q3SRMOxGivLhBNaUdC64hDTQwejJ+H0T/NB1XMtTVEwNTrfFF3gAxiyW0Bu/xWEGhjVKgUcMhCrUy2+uCWg==", + "dev": true, + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4", + "isarray": "^1.0.0" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "buffer-indexof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-indexof/-/buffer-indexof-1.1.1.tgz", + "integrity": "sha512-4/rOEg86jivtPTeOUUT61jJO1Ya1TrR/OkqCSZDyq84WJh3LuuiphBYJN+fm5xufIk4XAFcEwte/8WzC8If/1g==", + "dev": true + }, + "buffer-xor": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", + "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", + "dev": true + }, + "builtin-status-codes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", + "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", + "dev": true + }, + "bytes": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", + "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", + "dev": true + }, + "cacache": { + "version": "13.0.1", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-13.0.1.tgz", + "integrity": "sha512-5ZvAxd05HDDU+y9BVvcqYu2LLXmPnQ0hW62h32g4xBTgL/MppR4/04NHfj/ycM2y6lmTnbw6HVi+1eN0Psba6w==", + "dev": true, + "requires": { + "chownr": "^1.1.2", + "figgy-pudding": "^3.5.1", + "fs-minipass": "^2.0.0", + "glob": "^7.1.4", + "graceful-fs": "^4.2.2", + "infer-owner": "^1.0.4", + "lru-cache": "^5.1.1", + "minipass": "^3.0.0", + "minipass-collect": "^1.0.2", + "minipass-flush": "^1.0.5", + "minipass-pipeline": "^1.2.2", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "p-map": "^3.0.0", + "promise-inflight": "^1.0.1", + "rimraf": "^2.7.1", + "ssri": "^7.0.0", + "unique-filename": "^1.1.1" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "call-me-maybe": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.1.tgz", + "integrity": "sha1-JtII6onje1y95gJQoV8DHBak1ms=", + "dev": true + }, + "caller-callsite": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-callsite/-/caller-callsite-2.0.0.tgz", + "integrity": "sha1-hH4PzgoiN1CpoCfFSzNzGtMVQTQ=", + "dev": true, + "requires": { + "callsites": "^2.0.0" + } + }, + "caller-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/caller-path/-/caller-path-2.0.0.tgz", + "integrity": "sha1-Ro+DBE42mrIBD6xfBs7uFbsssfQ=", + "dev": true, + "requires": { + "caller-callsite": "^2.0.0" + } + }, + "callsites": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-2.0.0.tgz", + "integrity": "sha1-BuuE8A7qQT2oav/vrL/7Ngk7PFA=", + "dev": true + }, + "camel-case": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", + "integrity": "sha1-yjw2iKTpzzpM2nd9xNy8cTJJz3M=", + "dev": true, + "requires": { + "no-case": "^2.2.0", + "upper-case": "^1.1.1" + } + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "caniuse-api": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/caniuse-api/-/caniuse-api-3.0.0.tgz", + "integrity": "sha512-bsTwuIg/BZZK/vreVTYYbSWoe2F+71P7K5QGEX+pT250DZbfU1MQ5prOKpPR+LL6uWKK3KMwMCAS74QB3Um1uw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-lite": "^1.0.0", + "lodash.memoize": "^4.1.2", + "lodash.uniq": "^4.5.0" + } + }, + "caniuse-lite": { + "version": "1.0.30001083", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001083.tgz", + "integrity": "sha512-CnYJ27awX4h7yj5glfK7r1TOI13LBytpLzEgfj0s4mY75/F8pnQcYjL+oVpmS38FB59+vU0gscQ9D8tc+lIXvA==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "charenc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", + "integrity": "sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=", + "dev": true + }, + "chart.js": { + "version": "2.9.3", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.3.tgz", + "integrity": "sha512-+2jlOobSk52c1VU6fzkh3UwqHMdSlgH1xFv9FKMqHiNCpXsGPQa/+81AFa+i3jZ253Mq9aAycPwDjnn1XbRNNw==", + "requires": { + "chartjs-color": "^2.1.0", + "moment": "^2.10.2" + } + }, + "chartjs-color": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/chartjs-color/-/chartjs-color-2.4.1.tgz", + "integrity": "sha512-haqOg1+Yebys/Ts/9bLo/BqUcONQOdr/hoEr2LLTRl6C5LXctUdHxsCYfvQVg5JIxITrfCNUDr4ntqmQk9+/0w==", + "requires": { + "chartjs-color-string": "^0.6.0", + "color-convert": "^1.9.3" + } + }, + "chartjs-color-string": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/chartjs-color-string/-/chartjs-color-string-0.6.0.tgz", + "integrity": "sha512-TIB5OKn1hPJvO7JcteW4WY/63v6KwEdt6udfnDE9iCAZgy+V4SrbSxoIbTw/xkUIapjEI4ExGtD0+6D3KyFd7A==", + "requires": { + "color-name": "^1.0.0" + } + }, + "check-types": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/check-types/-/check-types-8.0.3.tgz", + "integrity": "sha512-YpeKZngUmG65rLudJ4taU7VLkOCTMhNl/u4ctNC56LQS/zJTyNH0Lrtwm1tfTsbLlwvlfsA2d1c8vCf/Kh2KwQ==", + "dev": true + }, + "chokidar": { + "version": "2.1.8", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.8.tgz", + "integrity": "sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==", + "dev": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "chownr": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", + "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", + "dev": true + }, + "chrome-trace-event": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", + "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "cipher-base": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", + "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "clean-css": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-4.2.3.tgz", + "integrity": "sha512-VcMWDN54ZN/DS+g58HYL5/n4Zrqe8vHJpGA8KdgUXFU4fuP/aHNw8eld9SyEIyabIMJX/0RaY/fplOo5hYLSFA==", + "dev": true, + "requires": { + "source-map": "~0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "clean-stack": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz", + "integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==", + "dev": true + }, + "cliui": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", + "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", + "dev": true, + "requires": { + "string-width": "^3.1.0", + "strip-ansi": "^5.2.0", + "wrap-ansi": "^5.1.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "clone-deep": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/clone-deep/-/clone-deep-4.0.1.tgz", + "integrity": "sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4", + "kind-of": "^6.0.2", + "shallow-clone": "^3.0.0" + } + }, + "coa": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/coa/-/coa-2.0.2.tgz", + "integrity": "sha512-q5/jG+YQnSy4nRTV4F7lPepBJZ8qBNJJDBuJdoejDyLXgmL7IEo+Le2JDZudFTFt7mrCqIRaSjws4ygRCTCAXA==", + "dev": true, + "requires": { + "@types/q": "^1.5.1", + "chalk": "^2.4.1", + "q": "^1.1.2" + } + }, + "code-point-at": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", + "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", + "dev": true + }, + "collect.js": { + "version": "4.27.3", + "resolved": "https://registry.npmjs.org/collect.js/-/collect.js-4.27.3.tgz", + "integrity": "sha512-2nmoyhUJbhjVVE0W9W0cSBeg8/PL3ObGe1ijj9WDlLG3RrpvePsBZd6p3uTm1dTAUKJVd3qT8mnH6iXCdENEHQ==", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/color/-/color-3.1.2.tgz", + "integrity": "sha512-vXTJhHebByxZn3lDvDJYw4lR5+uB3vuoHsuYA5AKuxRVn5wzzIfQKGLBmgdVRHKTJYeK5rvJcHnrd0Li49CFpg==", + "dev": true, + "requires": { + "color-convert": "^1.9.1", + "color-string": "^1.5.2" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=" + }, + "color-string": { + "version": "1.5.3", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.5.3.tgz", + "integrity": "sha512-dC2C5qeWoYkxki5UAXapdjqO672AM4vZuPGRQfO8b5HKuKGBbKWpITyDYN7TOFKvRW7kOgAn3746clDBMDJyQw==", + "dev": true, + "requires": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, + "commander": { + "version": "2.17.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.17.1.tgz", + "integrity": "sha512-wPMUt6FnH2yzG95SA6mzjQOEKUU3aLaDEmzs1ti+1E9h+CsrZghRlqEM/EJ4KscsQVG8uNN4uVreUeT8+drlgg==", + "dev": true + }, + "commondir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", + "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true + }, + "compose-function": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/compose-function/-/compose-function-3.0.3.tgz", + "integrity": "sha1-ntZ18TzFRQHTCVCkhv9qe6OrGF8=", + "dev": true, + "requires": { + "arity-n": "^1.0.4" + } + }, + "compressible": { + "version": "2.0.18", + "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.18.tgz", + "integrity": "sha512-AF3r7P5dWxL8MxyITRMlORQNaOA2IkAFaTr4k7BUumjPtRpGDTZpl0Pb1XCO6JeDCBdp126Cgs9sMxqSjgYyRg==", + "dev": true, + "requires": { + "mime-db": ">= 1.43.0 < 2" + } + }, + "compression": { + "version": "1.7.4", + "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz", + "integrity": "sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ==", + "dev": true, + "requires": { + "accepts": "~1.3.5", + "bytes": "3.0.0", + "compressible": "~2.0.16", + "debug": "2.6.9", + "on-headers": "~1.0.2", + "safe-buffer": "5.1.2", + "vary": "~1.1.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "concat-stream": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", + "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^2.2.2", + "typedarray": "^0.0.6" + } + }, + "concatenate": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/concatenate/-/concatenate-0.0.2.tgz", + "integrity": "sha1-C0nW6MQQR9dyjNyNYqCGYjOXtJ8=", + "dev": true, + "requires": { + "globs": "^0.1.2" + } + }, + "connect-history-api-fallback": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/connect-history-api-fallback/-/connect-history-api-fallback-1.6.0.tgz", + "integrity": "sha512-e54B99q/OUoH64zYYRf3HBP5z24G38h5D3qXu23JGRoigpX5Ss4r9ZnDk3g0Z8uQC2x2lPaJ+UlWBc1ZWBWdLg==", + "dev": true + }, + "console-browserify": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.2.0.tgz", + "integrity": "sha512-ZMkYO/LkF17QvCPqM0gxw8yUzigAOZOSWSHg91FH6orS7vcEj5dVZTidN2fQ14yBSdg97RqhSNwLUXInd52OTA==", + "dev": true + }, + "consolidate": { + "version": "0.15.1", + "resolved": "https://registry.npmjs.org/consolidate/-/consolidate-0.15.1.tgz", + "integrity": "sha512-DW46nrsMJgy9kqAbPt5rKaCr7uFtpo4mSUvLHIUbJEjm0vo+aY5QLwBUq3FK4tRnJr/X0Psc0C4jf/h+HtXSMw==", + "dev": true, + "requires": { + "bluebird": "^3.1.1" + } + }, + "constants-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", + "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", + "dev": true + }, + "content-disposition": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.3.tgz", + "integrity": "sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g==", + "dev": true, + "requires": { + "safe-buffer": "5.1.2" + } + }, + "content-type": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", + "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==", + "dev": true + }, + "convert-source-map": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.7.0.tgz", + "integrity": "sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "cookie": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz", + "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg==", + "dev": true + }, + "cookie-signature": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", + "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", + "dev": true + }, + "copy-concurrently": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", + "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "fs-write-stream-atomic": "^1.0.8", + "iferr": "^0.1.5", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.0" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true + }, + "core-js-compat": { + "version": "3.6.5", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.6.5.tgz", + "integrity": "sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng==", + "dev": true, + "requires": { + "browserslist": "^4.8.5", + "semver": "7.0.0" + }, + "dependencies": { + "semver": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.0.0.tgz", + "integrity": "sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==", + "dev": true + } + } + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true + }, + "cosmiconfig": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-5.2.1.tgz", + "integrity": "sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==", + "dev": true, + "requires": { + "import-fresh": "^2.0.0", + "is-directory": "^0.3.1", + "js-yaml": "^3.13.1", + "parse-json": "^4.0.0" + } + }, + "create-ecdh": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", + "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "elliptic": "^6.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "create-hash": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", + "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.1", + "inherits": "^2.0.1", + "md5.js": "^1.3.4", + "ripemd160": "^2.0.1", + "sha.js": "^2.4.0" + } + }, + "create-hmac": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", + "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", + "dev": true, + "requires": { + "cipher-base": "^1.0.3", + "create-hash": "^1.1.0", + "inherits": "^2.0.1", + "ripemd160": "^2.0.0", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "cross-env": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-7.0.2.tgz", + "integrity": "sha512-KZP/bMEOJEDCkDQAyRhu3RL2ZO/SUVrxQVI0G3YEQ+OLbRA3c6zgixe8Mq8a/z7+HKlNEjo8oiLUs8iRijY2Rw==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.1" + } + }, + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "crypt": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", + "integrity": "sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=", + "dev": true + }, + "crypto-browserify": { + "version": "3.12.0", + "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", + "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", + "dev": true, + "requires": { + "browserify-cipher": "^1.0.0", + "browserify-sign": "^4.0.0", + "create-ecdh": "^4.0.0", + "create-hash": "^1.1.0", + "create-hmac": "^1.1.0", + "diffie-hellman": "^5.0.0", + "inherits": "^2.0.1", + "pbkdf2": "^3.0.3", + "public-encrypt": "^4.0.0", + "randombytes": "^2.0.0", + "randomfill": "^1.0.3" + } + }, + "css": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/css/-/css-2.2.4.tgz", + "integrity": "sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "source-map": "^0.6.1", + "source-map-resolve": "^0.5.2", + "urix": "^0.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-color-names": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/css-color-names/-/css-color-names-0.0.4.tgz", + "integrity": "sha1-gIrcLnnPhHOAabZGyyDsJ762KeA=", + "dev": true + }, + "css-declaration-sorter": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/css-declaration-sorter/-/css-declaration-sorter-4.0.1.tgz", + "integrity": "sha512-BcxQSKTSEEQUftYpBVnsH4SF05NTuBokb19/sBt6asXGKZ/6VP7PLG1CBCkFDYOnhXhPh0jMhO6xZ71oYHXHBA==", + "dev": true, + "requires": { + "postcss": "^7.0.1", + "timsort": "^0.3.0" + } + }, + "css-loader": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/css-loader/-/css-loader-1.0.1.tgz", + "integrity": "sha512-+ZHAZm/yqvJ2kDtPne3uX0C+Vr3Zn5jFn2N4HywtS5ujwvsVkyg0VArEXpl3BgczDA8anieki1FIzhchX4yrDw==", + "dev": true, + "requires": { + "babel-code-frame": "^6.26.0", + "css-selector-tokenizer": "^0.7.0", + "icss-utils": "^2.1.0", + "loader-utils": "^1.0.2", + "lodash": "^4.17.11", + "postcss": "^6.0.23", + "postcss-modules-extract-imports": "^1.2.0", + "postcss-modules-local-by-default": "^1.2.0", + "postcss-modules-scope": "^1.1.0", + "postcss-modules-values": "^1.3.0", + "postcss-value-parser": "^3.3.0", + "source-list-map": "^2.0.0" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-2.1.0.tgz", + "integrity": "sha512-Dqk7LQKpwLoH3VovzZnkzegqNSuAziQyNZUcrdDM401iY+R5NkGBXGmtO05/yaXQziALuPogeG0b7UAgjnTJTQ==", + "dev": true, + "requires": { + "boolbase": "^1.0.0", + "css-what": "^3.2.1", + "domutils": "^1.7.0", + "nth-check": "^1.0.2" + } + }, + "css-select-base-adapter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/css-select-base-adapter/-/css-select-base-adapter-0.1.1.tgz", + "integrity": "sha512-jQVeeRG70QI08vSTwf1jHxp74JoZsr2XSgETae8/xC8ovSnL2WF87GTLO86Sbwdt2lK4Umg4HnnwMO4YF3Ce7w==", + "dev": true + }, + "css-selector-tokenizer": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/css-selector-tokenizer/-/css-selector-tokenizer-0.7.2.tgz", + "integrity": "sha512-yj856NGuAymN6r8bn8/Jl46pR+OC3eEvAhfGYDUe7YPtTPAYrSSw4oAniZ9Y8T5B92hjhwTBLUen0/vKPxf6pw==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "fastparse": "^1.1.2", + "regexpu-core": "^4.6.0" + } + }, + "css-tree": { + "version": "1.0.0-alpha.37", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.37.tgz", + "integrity": "sha512-DMxWJg0rnz7UgxKT0Q1HU/L9BeJI0M6ksor0OgqOnF+aRCDWg/N2641HmVyU9KVIu0OVVWOb2IpC9A+BJRnejg==", + "dev": true, + "requires": { + "mdn-data": "2.0.4", + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "css-what": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", + "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==", + "dev": true + }, + "cssesc": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/cssesc/-/cssesc-3.0.0.tgz", + "integrity": "sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==", + "dev": true + }, + "cssnano": { + "version": "4.1.10", + "resolved": "https://registry.npmjs.org/cssnano/-/cssnano-4.1.10.tgz", + "integrity": "sha512-5wny+F6H4/8RgNlaqab4ktc3e0/blKutmq8yNlBFXA//nSFFAqAngjNVRzUvCgYROULmZZUoosL/KSoZo5aUaQ==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "cssnano-preset-default": "^4.0.7", + "is-resolvable": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "cssnano-preset-default": { + "version": "4.0.7", + "resolved": "https://registry.npmjs.org/cssnano-preset-default/-/cssnano-preset-default-4.0.7.tgz", + "integrity": "sha512-x0YHHx2h6p0fCl1zY9L9roD7rnlltugGu7zXSKQx6k2rYw0Hi3IqxcoAGF7u9Q5w1nt7vK0ulxV8Lo+EvllGsA==", + "dev": true, + "requires": { + "css-declaration-sorter": "^4.0.1", + "cssnano-util-raw-cache": "^4.0.1", + "postcss": "^7.0.0", + "postcss-calc": "^7.0.1", + "postcss-colormin": "^4.0.3", + "postcss-convert-values": "^4.0.1", + "postcss-discard-comments": "^4.0.2", + "postcss-discard-duplicates": "^4.0.2", + "postcss-discard-empty": "^4.0.1", + "postcss-discard-overridden": "^4.0.1", + "postcss-merge-longhand": "^4.0.11", + "postcss-merge-rules": "^4.0.3", + "postcss-minify-font-values": "^4.0.2", + "postcss-minify-gradients": "^4.0.2", + "postcss-minify-params": "^4.0.2", + "postcss-minify-selectors": "^4.0.2", + "postcss-normalize-charset": "^4.0.1", + "postcss-normalize-display-values": "^4.0.2", + "postcss-normalize-positions": "^4.0.2", + "postcss-normalize-repeat-style": "^4.0.2", + "postcss-normalize-string": "^4.0.2", + "postcss-normalize-timing-functions": "^4.0.2", + "postcss-normalize-unicode": "^4.0.1", + "postcss-normalize-url": "^4.0.1", + "postcss-normalize-whitespace": "^4.0.2", + "postcss-ordered-values": "^4.1.2", + "postcss-reduce-initial": "^4.0.3", + "postcss-reduce-transforms": "^4.0.2", + "postcss-svgo": "^4.0.2", + "postcss-unique-selectors": "^4.0.1" + } + }, + "cssnano-util-get-arguments": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-arguments/-/cssnano-util-get-arguments-4.0.0.tgz", + "integrity": "sha1-7ToIKZ8h11dBsg87gfGU7UnMFQ8=", + "dev": true + }, + "cssnano-util-get-match": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cssnano-util-get-match/-/cssnano-util-get-match-4.0.0.tgz", + "integrity": "sha1-wOTKB/U4a7F+xeUiULT1lhNlFW0=", + "dev": true + }, + "cssnano-util-raw-cache": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-raw-cache/-/cssnano-util-raw-cache-4.0.1.tgz", + "integrity": "sha512-qLuYtWK2b2Dy55I8ZX3ky1Z16WYsx544Q0UWViebptpwn/xDBmog2TLg4f+DBMg1rJ6JDWtn96WHbOKDWt1WQA==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "cssnano-util-same-parent": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/cssnano-util-same-parent/-/cssnano-util-same-parent-4.0.1.tgz", + "integrity": "sha512-WcKx5OY+KoSIAxBW6UBBRay1U6vkYheCdjyVNDm85zt5K9mHoGOfsOsqIszfAqrQQFIIKgjh2+FDgIj/zsl21Q==", + "dev": true + }, + "csso": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/csso/-/csso-4.0.3.tgz", + "integrity": "sha512-NL3spysxUkcrOgnpsT4Xdl2aiEiBG6bXswAABQVHcMrfjjBisFOKwLDOmf4wf32aPdcJws1zds2B0Rg+jqMyHQ==", + "dev": true, + "requires": { + "css-tree": "1.0.0-alpha.39" + }, + "dependencies": { + "css-tree": { + "version": "1.0.0-alpha.39", + "resolved": "https://registry.npmjs.org/css-tree/-/css-tree-1.0.0-alpha.39.tgz", + "integrity": "sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==", + "dev": true, + "requires": { + "mdn-data": "2.0.6", + "source-map": "^0.6.1" + } + }, + "mdn-data": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.6.tgz", + "integrity": "sha512-rQvjv71olwNHgiTbfPZFkJtjNMciWgswYeciZhtvWLO8bmX3TnhyA62I6sTWOyZssWHJJjY6/KiWwqQsWWsqOA==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "cyclist": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-1.0.1.tgz", + "integrity": "sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk=", + "dev": true + }, + "d": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/d/-/d-1.0.1.tgz", + "integrity": "sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==", + "dev": true, + "requires": { + "es5-ext": "^0.10.50", + "type": "^1.0.1" + } + }, + "de-indent": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/de-indent/-/de-indent-1.0.2.tgz", + "integrity": "sha1-sgOOhG3DO6pXlhKNCAS0VbjB4h0=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decamelize": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", + "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", + "dev": true + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true + }, + "deep-equal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/deep-equal/-/deep-equal-1.1.1.tgz", + "integrity": "sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==", + "dev": true, + "requires": { + "is-arguments": "^1.0.4", + "is-date-object": "^1.0.1", + "is-regex": "^1.0.4", + "object-is": "^1.0.1", + "object-keys": "^1.1.1", + "regexp.prototype.flags": "^1.2.0" + } + }, + "deepmerge": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-2.2.1.tgz", + "integrity": "sha512-R9hc1Xa/NOBi9WRVUWg19rl1UB7Tt4kuPd+thNJgFZoxXsTz7ncaPaeIm+40oSGuP33DfMb4sZt1QIGiJzC4EA==", + "dev": true + }, + "default-gateway": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/default-gateway/-/default-gateway-4.2.0.tgz", + "integrity": "sha512-h6sMrVB1VMWVrW13mSc6ia/DwYYw5MN6+exNu1OaJeFac5aSAvwM7lZ0NVfTABuSkQelr4h5oebg3KB1XPdjgA==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "ip-regex": "^2.1.0" + } + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "del": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/del/-/del-4.1.1.tgz", + "integrity": "sha512-QwGuEUouP2kVwQenAsOof5Fv8K9t3D8Ca8NxcXKrIpEHjTXK5J2nXLdP+ALI1cgv8wj7KuwBhTwBkOZSJKM5XQ==", + "dev": true, + "requires": { + "@types/glob": "^7.1.1", + "globby": "^6.1.0", + "is-path-cwd": "^2.0.0", + "is-path-in-cwd": "^2.0.0", + "p-map": "^2.0.0", + "pify": "^4.0.1", + "rimraf": "^2.6.3" + }, + "dependencies": { + "globby": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/globby/-/globby-6.1.0.tgz", + "integrity": "sha1-9abXDoOV4hyFj7BInWTfAkJNUGw=", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "glob": "^7.0.3", + "object-assign": "^4.0.1", + "pify": "^2.0.0", + "pinkie-promise": "^2.0.0" + }, + "dependencies": { + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + } + } + }, + "p-map": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-2.1.0.tgz", + "integrity": "sha512-y3b8Kpd8OAN444hxfBbFfj1FY/RjtTd8tzYwhUqNYXx0fXx2iX4maP4Qr6qhIKbQXI02wTLAda4fYUbDagTUFw==", + "dev": true + } + } + }, + "depd": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz", + "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak=", + "dev": true + }, + "des.js": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.1.tgz", + "integrity": "sha512-Q0I4pfFrv2VPd34/vfLrFOoRmlYj3OV50i7fskps1jZWK1kApMWWT9G6RRUeYedLcBDIhnSDaUvJMb3AhUlaEA==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0" + } + }, + "destroy": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz", + "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA=", + "dev": true + }, + "detect-file": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", + "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", + "dev": true + }, + "detect-node": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.0.4.tgz", + "integrity": "sha512-ZIzRpLJrOj7jjP2miAtgqIfmzbxa4ZOr5jJc601zklsfEx9oTzmmj2nVpIPRpNlRTIh8lc1kyViIY7BWSGNmKw==", + "dev": true + }, + "diffie-hellman": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", + "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "miller-rabin": "^4.0.0", + "randombytes": "^2.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "dir-glob": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-2.0.0.tgz", + "integrity": "sha512-37qirFDz8cA5fimp9feo43fSuRo2gHwaIn6dXL8Ber1dGwUosDrGZeCCXq57WnIqE4aQ+u3eQZzsk1yOzhdwag==", + "dev": true, + "requires": { + "arrify": "^1.0.1", + "path-type": "^3.0.0" + } + }, + "dns-equal": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/dns-equal/-/dns-equal-1.0.0.tgz", + "integrity": "sha1-s55/HabrCnW6nBcySzR1PEfgZU0=", + "dev": true + }, + "dns-packet": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/dns-packet/-/dns-packet-1.3.1.tgz", + "integrity": "sha512-0UxfQkMhYAUaZI+xrNZOz/as5KgDU0M/fQ9b6SpkyLbk3GEswDi6PADJVaYJradtRVsRIlF1zLyOodbcTCDzUg==", + "dev": true, + "requires": { + "ip": "^1.1.0", + "safe-buffer": "^5.0.1" + } + }, + "dns-txt": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/dns-txt/-/dns-txt-2.0.2.tgz", + "integrity": "sha1-uR2Ab10nGI5Ks+fRB9iBocxGQrY=", + "dev": true, + "requires": { + "buffer-indexof": "^1.0.0" + } + }, + "dom-serializer": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", + "integrity": "sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==", + "dev": true, + "requires": { + "domelementtype": "^2.0.1", + "entities": "^2.0.0" + }, + "dependencies": { + "domelementtype": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.0.1.tgz", + "integrity": "sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==", + "dev": true + } + } + }, + "domain-browser": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", + "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", + "dev": true + }, + "domelementtype": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", + "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==", + "dev": true + }, + "domutils": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.7.0.tgz", + "integrity": "sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==", + "dev": true, + "requires": { + "dom-serializer": "0", + "domelementtype": "1" + } + }, + "dot-prop": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.2.0.tgz", + "integrity": "sha512-uEUyaDKoSQ1M4Oq8l45hSE26SnTxL6snNnqvK/VWx5wJhmff5z0FUVJDKDanor/6w3kzE3i7XZOk+7wC0EXr1A==", + "dev": true, + "requires": { + "is-obj": "^2.0.0" + } + }, + "dotenv": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-6.2.0.tgz", + "integrity": "sha512-HygQCKUBSFl8wKQZBSemMywRWcEDNidvNbjGVyZu3nbZ8qq9ubiPoGLMdRDpfSrpkkm9BXYFkpKxxFX38o/76w==", + "dev": true + }, + "dotenv-expand": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-4.2.0.tgz", + "integrity": "sha1-3vHxyl1gWdJKdm5YeULCEQbOEnU=", + "dev": true + }, + "duplexer": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/duplexer/-/duplexer-0.1.1.tgz", + "integrity": "sha1-rOb/gIwc5mtX0ev5eXessCM0z8E=", + "dev": true + }, + "duplexify": { + "version": "3.7.1", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", + "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", + "dev": true, + "requires": { + "end-of-stream": "^1.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.0.0", + "stream-shift": "^1.0.0" + } + }, + "ee-first": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", + "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=", + "dev": true + }, + "ejs": { + "version": "2.7.4", + "resolved": "https://registry.npmjs.org/ejs/-/ejs-2.7.4.tgz", + "integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA==", + "dev": true + }, + "electron-to-chromium": { + "version": "1.3.473", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.473.tgz", + "integrity": "sha512-smevlzzMNz3vMz6OLeeCq5HRWEj2AcgccNPYnAx4Usx0IOciq9DU36RJcICcS09hXoY7t7deRfVYKD14IrGb9A==", + "dev": true + }, + "elliptic": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.2.tgz", + "integrity": "sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw==", + "dev": true, + "requires": { + "bn.js": "^4.4.0", + "brorand": "^1.0.1", + "hash.js": "^1.0.0", + "hmac-drbg": "^1.0.0", + "inherits": "^2.0.1", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.0" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "emojis-list": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-3.0.0.tgz", + "integrity": "sha512-/kyM18EfinwXZbno9FyUGeFh87KC8HRQBQGildHZbEuRyWFOmv1U10o9BBp8XVZDVNNuQKyIGIu5ZYAAXJ0V2Q==", + "dev": true + }, + "encodeurl": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz", + "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k=", + "dev": true + }, + "end-of-stream": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", + "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, + "requires": { + "once": "^1.4.0" + } + }, + "enhanced-resolve": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz", + "integrity": "sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.5.0", + "tapable": "^1.0.0" + }, + "dependencies": { + "memory-fs": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.5.0.tgz", + "integrity": "sha512-jA0rdU5KoQMC0e6ppoNRtpp6vjFq6+NY7r8hywnC7V+1Xj/MtHwGIbB1QaK/dunyjWteJzmkpd7ooeWg10T7GA==", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + } + } + }, + "entities": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/entities/-/entities-2.0.3.tgz", + "integrity": "sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==", + "dev": true + }, + "errno": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", + "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", + "dev": true, + "requires": { + "prr": "~1.0.1" + } + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "error-stack-parser": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/error-stack-parser/-/error-stack-parser-2.0.6.tgz", + "integrity": "sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==", + "dev": true, + "requires": { + "stackframe": "^1.1.1" + } + }, + "es-abstract": { + "version": "1.17.6", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.17.6.tgz", + "integrity": "sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.1", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "has-symbols": "^1.0.1", + "is-callable": "^1.2.0", + "is-regex": "^1.1.0", + "object-inspect": "^1.7.0", + "object-keys": "^1.1.1", + "object.assign": "^4.1.0", + "string.prototype.trimend": "^1.0.1", + "string.prototype.trimstart": "^1.0.1" + } + }, + "es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "es5-ext": { + "version": "0.10.53", + "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.53.tgz", + "integrity": "sha512-Xs2Stw6NiNHWypzRTY1MtaG/uJlwCk8kH81920ma8mvN8Xq1gsfhZvpkImLQArw8AHnv8MT2I45J3c0R8slE+Q==", + "dev": true, + "requires": { + "es6-iterator": "~2.0.3", + "es6-symbol": "~3.1.3", + "next-tick": "~1.0.0" + } + }, + "es6-iterator": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz", + "integrity": "sha1-p96IkUGgWpSwhUQDstCg+/qY87c=", + "dev": true, + "requires": { + "d": "1", + "es5-ext": "^0.10.35", + "es6-symbol": "^3.1.1" + } + }, + "es6-symbol": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.3.tgz", + "integrity": "sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==", + "dev": true, + "requires": { + "d": "^1.0.1", + "ext": "^1.1.2" + } + }, + "es6-templates": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/es6-templates/-/es6-templates-0.2.3.tgz", + "integrity": "sha1-XLmsn7He1usSOTQrgdeSu7QHjuQ=", + "dev": true, + "requires": { + "recast": "~0.11.12", + "through": "~2.3.6" + } + }, + "escape-html": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", + "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg=", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "esprima": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-3.1.3.tgz", + "integrity": "sha1-/cpRzuYTOJXjyI1TXOSdv/YqRjM=", + "dev": true + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz", + "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==", + "dev": true + }, + "esutils": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz", + "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==", + "dev": true + }, + "etag": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", + "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=", + "dev": true + }, + "eventemitter3": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.4.tgz", + "integrity": "sha512-rlaVLnVxtxvoyLsQQFBx53YmXHDxRIzzTLbdfxqi4yocpSjAxXwkU0cScM5JgSKMqEhrZpnvQ2D9gjylR0AimQ==", + "dev": true + }, + "events": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/events/-/events-3.1.0.tgz", + "integrity": "sha512-Rv+u8MLHNOdMjTAFeT3nCjHn2aGlx435FP/sDHNaRhDEMwyI/aB22Kj2qIN8R0cw3z28psEQLYwxVKLsKrMgWg==", + "dev": true + }, + "eventsource": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/eventsource/-/eventsource-1.0.7.tgz", + "integrity": "sha512-4Ln17+vVT0k8aWq+t/bF5arcS3EpT9gYtW66EPacdj/mAFevznsnyoHLPy2BA8gbIQeIHoPsvwmfBftfcG//BQ==", + "dev": true, + "requires": { + "original": "^1.0.0" + } + }, + "evp_bytestokey": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", + "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", + "dev": true, + "requires": { + "md5.js": "^1.3.4", + "safe-buffer": "^5.1.1" + } + }, + "execa": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", + "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.0", + "get-stream": "^4.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "dependencies": { + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "expand-tilde": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", + "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", + "dev": true, + "requires": { + "homedir-polyfill": "^1.0.1" + } + }, + "express": { + "version": "4.17.1", + "resolved": "https://registry.npmjs.org/express/-/express-4.17.1.tgz", + "integrity": "sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g==", + "dev": true, + "requires": { + "accepts": "~1.3.7", + "array-flatten": "1.1.1", + "body-parser": "1.19.0", + "content-disposition": "0.5.3", + "content-type": "~1.0.4", + "cookie": "0.4.0", + "cookie-signature": "1.0.6", + "debug": "2.6.9", + "depd": "~1.1.2", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "finalhandler": "~1.1.2", + "fresh": "0.5.2", + "merge-descriptors": "1.0.1", + "methods": "~1.1.2", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "path-to-regexp": "0.1.7", + "proxy-addr": "~2.0.5", + "qs": "6.7.0", + "range-parser": "~1.2.1", + "safe-buffer": "5.1.2", + "send": "0.17.1", + "serve-static": "1.14.1", + "setprototypeof": "1.1.1", + "statuses": "~1.5.0", + "type-is": "~1.6.18", + "utils-merge": "1.0.1", + "vary": "~1.1.2" + }, + "dependencies": { + "array-flatten": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", + "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI=", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "ext": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/ext/-/ext-1.4.0.tgz", + "integrity": "sha512-Key5NIsUxdqKg3vIsdw9dSuXpPCQ297y6wBjL30edxwPgt2E44WcWBZey/ZvUc6sERLTxKdyCu4gZFmUbk1Q7A==", + "dev": true, + "requires": { + "type": "^2.0.0" + }, + "dependencies": { + "type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/type/-/type-2.0.0.tgz", + "integrity": "sha512-KBt58xCHry4Cejnc2ISQAF7QY+ORngsWfxezO68+12hKV6lQY8P/psIkcbjeHWn7MqcgciWJyCCevFMJdIXpow==", + "dev": true + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "extract-text-webpack-plugin": { + "version": "4.0.0-beta.0", + "resolved": "https://registry.npmjs.org/extract-text-webpack-plugin/-/extract-text-webpack-plugin-4.0.0-beta.0.tgz", + "integrity": "sha512-Hypkn9jUTnFr0DpekNam53X47tXn3ucY08BQumv7kdGgeVUBLq3DJHJTi6HNxv4jl9W+Skxjz9+RnK0sJyqqjA==", + "dev": true, + "requires": { + "async": "^2.4.1", + "loader-utils": "^1.1.0", + "schema-utils": "^0.4.5", + "webpack-sources": "^1.1.0" + }, + "dependencies": { + "schema-utils": { + "version": "0.4.7", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-0.4.7.tgz", + "integrity": "sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", + "dev": true + }, + "fast-glob": { + "version": "2.2.7", + "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-2.2.7.tgz", + "integrity": "sha512-g1KuQwHOZAmOZMuBtHdxDtju+T2RT8jgCC9aANsbpdiDDTSnjgfuVsIBNKbUeJI3oKMRExcfNDtJl4OhbffMsw==", + "dev": true, + "requires": { + "@mrmlnc/readdir-enhanced": "^2.2.1", + "@nodelib/fs.stat": "^1.1.2", + "glob-parent": "^3.1.0", + "is-glob": "^4.0.0", + "merge2": "^1.2.3", + "micromatch": "^3.1.10" + } + }, + "fast-json-stable-stringify": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", + "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", + "dev": true + }, + "fastparse": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/fastparse/-/fastparse-1.1.2.tgz", + "integrity": "sha512-483XLLxTVIwWK3QTrMGRqUfUpoOs/0hbQrl2oz4J0pAcm3A3bu84wxTFqGqkJzewCLdME38xJLJAxBABfQT8sQ==", + "dev": true + }, + "faye-websocket": { + "version": "0.10.0", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.10.0.tgz", + "integrity": "sha1-TkkvjQTftviQA1B/btvy1QHnxvQ=", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "figgy-pudding": { + "version": "3.5.2", + "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.2.tgz", + "integrity": "sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==", + "dev": true + }, + "file-loader": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/file-loader/-/file-loader-2.0.0.tgz", + "integrity": "sha512-YCsBfd1ZGCyonOKLxPiKPdu+8ld9HAaMEvJewzz+b2eTF7uL5Zm/HdBF6FjCrpCMRq25Mi0U1gl4pwn2TlH7hQ==", + "dev": true, + "requires": { + "loader-utils": "^1.0.2", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "file-type": { + "version": "10.11.0", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-10.11.0.tgz", + "integrity": "sha512-uzk64HRpUZyTGZtVuvrjP0FYxzQrBf4rojot6J65YMEbwBLB0CWm0CLojVpwpmFmxcE/lkvYICgfcGozbBq6rw==", + "dev": true + }, + "file-uri-to-path": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", + "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", + "dev": true, + "optional": true + }, + "filesize": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/filesize/-/filesize-3.6.1.tgz", + "integrity": "sha512-7KjR1vv6qnicaPMi1iiTcI85CyYwRO/PSFCu6SvqL8jN2Wjt/NIYQTFtFs7fSDCYOstUkEWIQGFUg5YZQfjlcg==", + "dev": true + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "finalhandler": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.2.tgz", + "integrity": "sha512-aAWcW57uxVNrQZqFXjITpW3sIUQmHGG3qSb9mUah9MgMC4NeWhNOlNjXEYq3HjRAvL6arUviZGGJsBg6z0zsWA==", + "dev": true, + "requires": { + "debug": "2.6.9", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "on-finished": "~2.3.0", + "parseurl": "~1.3.3", + "statuses": "~1.5.0", + "unpipe": "~1.0.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + } + } + }, + "find-cache-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", + "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^2.0.0", + "pkg-dir": "^3.0.0" + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "findup-sync": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", + "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", + "dev": true, + "requires": { + "detect-file": "^1.0.0", + "is-glob": "^4.0.0", + "micromatch": "^3.0.4", + "resolve-dir": "^1.0.1" + } + }, + "flush-write-stream": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", + "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "readable-stream": "^2.3.6" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", + "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", + "dev": true, + "requires": { + "debug": "=3.1.0" + } + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true + }, + "forwarded": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz", + "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ=", + "dev": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fresh": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz", + "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac=", + "dev": true + }, + "friendly-errors-webpack-plugin": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/friendly-errors-webpack-plugin/-/friendly-errors-webpack-plugin-1.7.0.tgz", + "integrity": "sha512-K27M3VK30wVoOarP651zDmb93R9zF28usW4ocaK3mfQeIEI5BPht/EzZs5E8QLLwbLRJQMwscAjDxYPb1FuNiw==", + "dev": true, + "requires": { + "chalk": "^1.1.3", + "error-stack-parser": "^2.0.0", + "string-width": "^2.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", + "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=", + "dev": true + }, + "chalk": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", + "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", + "dev": true, + "requires": { + "ansi-styles": "^2.2.1", + "escape-string-regexp": "^1.0.2", + "has-ansi": "^2.0.0", + "strip-ansi": "^3.0.0", + "supports-color": "^2.0.0" + } + }, + "supports-color": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", + "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=", + "dev": true + } + } + }, + "from2": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", + "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "readable-stream": "^2.0.0" + } + }, + "fs-extra": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-7.0.1.tgz", + "integrity": "sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "jsonfile": "^4.0.0", + "universalify": "^0.1.0" + } + }, + "fs-minipass": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/fs-minipass/-/fs-minipass-2.1.0.tgz", + "integrity": "sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "fs-write-stream-atomic": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", + "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "iferr": "^0.1.5", + "imurmurhash": "^0.1.4", + "readable-stream": "1 || 2" + } + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", + "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", + "dev": true, + "optional": true, + "requires": { + "bindings": "^1.5.0", + "nan": "^2.12.1" + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "gensync": { + "version": "1.0.0-beta.1", + "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.1.tgz", + "integrity": "sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==", + "dev": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "get-stream": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", + "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", + "dev": true, + "requires": { + "pump": "^3.0.0" + } + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "glob-to-regexp": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz", + "integrity": "sha1-jFoUlNIGbFcMw7/kSWF1rMTVAqs=", + "dev": true + }, + "global-modules": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", + "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", + "dev": true, + "requires": { + "global-prefix": "^3.0.0" + }, + "dependencies": { + "global-prefix": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", + "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", + "dev": true, + "requires": { + "ini": "^1.3.5", + "kind-of": "^6.0.2", + "which": "^1.3.1" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "global-prefix": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", + "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.2", + "homedir-polyfill": "^1.0.1", + "ini": "^1.3.4", + "is-windows": "^1.0.1", + "which": "^1.2.14" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "globby": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/globby/-/globby-8.0.2.tgz", + "integrity": "sha512-yTzMmKygLp8RUpG1Ymu2VXPSJQZjNAZPD4ywgYEaG7e4tBJeUQBO8OpXrf1RCNcEs5alsoJYPAMiIHP0cmeC7w==", + "dev": true, + "requires": { + "array-union": "^1.0.1", + "dir-glob": "2.0.0", + "fast-glob": "^2.0.2", + "glob": "^7.1.2", + "ignore": "^3.3.5", + "pify": "^3.0.0", + "slash": "^1.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "globs": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/globs/-/globs-0.1.4.tgz", + "integrity": "sha512-D23dWbOq48vlOraoSigbcQV4tWrnhwk+E/Um2cMuDS3/5dwGmdFeA7L/vAvDhLFlQOTDqHcXh35m/71g2A2WzQ==", + "dev": true, + "requires": { + "glob": "^7.1.1" + } + }, + "graceful-fs": { + "version": "4.2.4", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.4.tgz", + "integrity": "sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==", + "dev": true + }, + "growly": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/growly/-/growly-1.3.0.tgz", + "integrity": "sha1-8QdIy+dq+WS3yWyTxrzCivEgwIE=", + "dev": true + }, + "gzip-size": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/gzip-size/-/gzip-size-5.1.1.tgz", + "integrity": "sha512-FNHi6mmoHvs1mxZAds4PpdCS6QG8B4C1krxJsMutgxl5t3+GlRTzzI3NEkifXx2pVsOvJdOGSmIgDhQ55FwdPA==", + "dev": true, + "requires": { + "duplexer": "^0.1.1", + "pify": "^4.0.1" + } + }, + "handle-thing": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", + "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-ansi": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", + "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.1.tgz", + "integrity": "sha512-PLcsoqu++dmEIZB+6totNFKq/7Do+Z0u4oT0zKOJNl3lYK6vGwwu2hjHs+68OEZbTjiUE9bgOABXbP/GvrS0Kg==", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hash-base": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.1.0.tgz", + "integrity": "sha512-1nmYp/rhMDiE7AYkDw+lLwlAzz0AntGIe51F3RfFfEqyQ3feY2eI/NcwC6umIQVOASPMsWJLJScWKSSvzL9IVA==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "readable-stream": "^3.6.0", + "safe-buffer": "^5.2.0" + }, + "dependencies": { + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + } + } + }, + "hash-sum": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hash-sum/-/hash-sum-1.0.2.tgz", + "integrity": "sha1-M7QHd3VMZDJXPBIMw4CLvRDUfwQ=", + "dev": true + }, + "hash.js": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", + "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "minimalistic-assert": "^1.0.1" + } + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "hex-color-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/hex-color-regex/-/hex-color-regex-1.1.0.tgz", + "integrity": "sha512-l9sfDFsuqtOqKDsQdqrMRk0U85RZc0RtOR9yPI7mRVOa4FsR/BVnZ0shmQRM96Ji99kYZP/7hn1cedc1+ApsTQ==", + "dev": true + }, + "hmac-drbg": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", + "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", + "dev": true, + "requires": { + "hash.js": "^1.0.3", + "minimalistic-assert": "^1.0.0", + "minimalistic-crypto-utils": "^1.0.1" + } + }, + "homedir-polyfill": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", + "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", + "dev": true, + "requires": { + "parse-passwd": "^1.0.0" + } + }, + "hoopy": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/hoopy/-/hoopy-0.1.4.tgz", + "integrity": "sha512-HRcs+2mr52W0K+x8RzcLzuPPmVIKMSv97RGHy0Ea9y/mpcaK+xTrjICA04KAHi4GRzxliNqNJEFYWHghy3rSfQ==", + "dev": true + }, + "hpack.js": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/hpack.js/-/hpack.js-2.1.6.tgz", + "integrity": "sha1-h3dMCUnlE/QuhFdbPEVoH63ioLI=", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "obuf": "^1.0.0", + "readable-stream": "^2.0.1", + "wbuf": "^1.1.0" + } + }, + "hsl-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsl-regex/-/hsl-regex-1.0.0.tgz", + "integrity": "sha1-1JMwx4ntgZ4nakwNJy3/owsY/m4=", + "dev": true + }, + "hsla-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/hsla-regex/-/hsla-regex-1.0.0.tgz", + "integrity": "sha1-wc56MWjIxmFAM6S194d/OyJfnDg=", + "dev": true + }, + "html-comment-regex": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/html-comment-regex/-/html-comment-regex-1.1.2.tgz", + "integrity": "sha512-P+M65QY2JQ5Y0G9KKdlDpo0zK+/OHptU5AaBwUfAIDJZk1MYf32Frm84EcOytfJE0t5JvkAnKlmjsXDnWzCJmQ==", + "dev": true + }, + "html-entities": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-1.3.1.tgz", + "integrity": "sha512-rhE/4Z3hIhzHAUKbW8jVcCyuT5oJCXXqhN/6mXXVCpzTmvJnoH2HL/bt3EZ6p55jbFJBeAe1ZNpL5BugLujxNA==", + "dev": true + }, + "html-loader": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/html-loader/-/html-loader-0.5.5.tgz", + "integrity": "sha512-7hIW7YinOYUpo//kSYcPB6dCKoceKLmOwjEMmhIobHuWGDVl0Nwe4l68mdG/Ru0wcUxQjVMEoZpkalZ/SE7zog==", + "dev": true, + "requires": { + "es6-templates": "^0.2.3", + "fastparse": "^1.1.1", + "html-minifier": "^3.5.8", + "loader-utils": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "html-minifier": { + "version": "3.5.21", + "resolved": "https://registry.npmjs.org/html-minifier/-/html-minifier-3.5.21.tgz", + "integrity": "sha512-LKUKwuJDhxNa3uf/LPR/KVjm/l3rBqtYeCOAekvG8F1vItxMUpueGd94i/asDDr8/1u7InxzFA5EeGjhhG5mMA==", + "dev": true, + "requires": { + "camel-case": "3.0.x", + "clean-css": "4.2.x", + "commander": "2.17.x", + "he": "1.2.x", + "param-case": "2.1.x", + "relateurl": "0.2.x", + "uglify-js": "3.4.x" + } + }, + "http-deceiver": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/http-deceiver/-/http-deceiver-1.2.7.tgz", + "integrity": "sha1-+nFolEq5pRnTN8sL7HKE3D5yPYc=", + "dev": true + }, + "http-errors": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.7.2.tgz", + "integrity": "sha512-uUQBt3H/cSIVfch6i1EuPNy/YsRSOUBXTVfZ+yR7Zjez3qjBz6i9+i4zjNaoqcoFVI4lQJ5plg63TvGfRSDCRg==", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.1", + "statuses": ">= 1.5.0 < 2", + "toidentifier": "1.0.0" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "http-proxy": { + "version": "1.18.1", + "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", + "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", + "dev": true, + "requires": { + "eventemitter3": "^4.0.0", + "follow-redirects": "^1.0.0", + "requires-port": "^1.0.0" + } + }, + "http-proxy-middleware": { + "version": "0.19.1", + "resolved": "https://registry.npmjs.org/http-proxy-middleware/-/http-proxy-middleware-0.19.1.tgz", + "integrity": "sha512-yHYTgWMQO8VvwNS22eLLloAkvungsKdKTLO8AJlftYIKNfJr3GK3zK0ZCfzDDGUBttdGc8xFy1mCitvNKQtC3Q==", + "dev": true, + "requires": { + "http-proxy": "^1.17.0", + "is-glob": "^4.0.0", + "lodash": "^4.17.11", + "micromatch": "^3.1.10" + } + }, + "https-browserify": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", + "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", + "dev": true + }, + "icheck-bootstrap": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/icheck-bootstrap/-/icheck-bootstrap-3.0.1.tgz", + "integrity": "sha512-Rj3SybdcMcayhsP4IJ+hmCNgCKclaFcs/5zwCuLXH1WMo468NegjhZVxbSNKhEjJjnwc4gKETogUmPYSQ9lEZQ==" + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "icss-replace-symbols": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/icss-replace-symbols/-/icss-replace-symbols-1.1.0.tgz", + "integrity": "sha1-Bupvg2ead0njhs/h/oEq5dsiPe0=", + "dev": true + }, + "icss-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/icss-utils/-/icss-utils-2.1.0.tgz", + "integrity": "sha1-g/Cg7DeL8yRheLbCrZE28TWxyWI=", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "ieee754": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", + "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", + "dev": true + }, + "iferr": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", + "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", + "dev": true + }, + "ignore": { + "version": "3.3.10", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-3.3.10.tgz", + "integrity": "sha512-Pgs951kaMm5GXP7MOvxERINe3gsaVjUWFm+UZPSq9xYriQAksyhg0csnS0KXSNRD5NmNdapXEpjxG49+AKh/ug==", + "dev": true + }, + "imagemin": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/imagemin/-/imagemin-6.1.0.tgz", + "integrity": "sha512-8ryJBL1CN5uSHpiBMX0rJw79C9F9aJqMnjGnrd/1CafegpNuA81RBAAru/jQQEOWlOJJlpRnlcVFF6wq+Ist0A==", + "dev": true, + "requires": { + "file-type": "^10.7.0", + "globby": "^8.0.1", + "make-dir": "^1.0.0", + "p-pipe": "^1.1.0", + "pify": "^4.0.1", + "replace-ext": "^1.0.0" + }, + "dependencies": { + "make-dir": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", + "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + } + } + }, + "img-loader": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/img-loader/-/img-loader-3.0.1.tgz", + "integrity": "sha512-0jDJqexgzOuq3zlXwFTBKJlMcaP1uXyl5t4Qu6b1IgXb3IwBDjPfVylBC8vHFIIESDw/S+5QkBbtBrt4T8wESA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0" + } + }, + "import-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-cwd/-/import-cwd-2.1.0.tgz", + "integrity": "sha1-qmzzbnInYShcs3HsZRn1PiQ1sKk=", + "dev": true, + "requires": { + "import-from": "^2.1.0" + } + }, + "import-fresh": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-2.0.0.tgz", + "integrity": "sha1-2BNVwVYS04bGH53dOSLUMEgipUY=", + "dev": true, + "requires": { + "caller-path": "^2.0.0", + "resolve-from": "^3.0.0" + } + }, + "import-from": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/import-from/-/import-from-2.1.0.tgz", + "integrity": "sha1-M1238qev/VOqpHHUuAId7ja387E=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "import-local": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", + "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", + "dev": true, + "requires": { + "pkg-dir": "^3.0.0", + "resolve-cwd": "^2.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "indent-string": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz", + "integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==", + "dev": true + }, + "indexes-of": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/indexes-of/-/indexes-of-1.0.1.tgz", + "integrity": "sha1-8w9xbI4r00bHtn0985FVZqfAVgc=", + "dev": true + }, + "infer-owner": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", + "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "ini": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", + "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "dev": true + }, + "internal-ip": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/internal-ip/-/internal-ip-4.3.0.tgz", + "integrity": "sha512-S1zBo1D6zcsyuC6PMmY5+55YMILQ9av8lotMx447Bq6SAgo/sDK6y6uUKmuYhW7eacnIhFfsPmCNYdDzsnnDCg==", + "dev": true, + "requires": { + "default-gateway": "^4.2.0", + "ipaddr.js": "^1.9.0" + } + }, + "interpret": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", + "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", + "dev": true + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "invert-kv": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", + "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", + "dev": true + }, + "ip": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", + "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=", + "dev": true + }, + "ip-regex": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-2.1.0.tgz", + "integrity": "sha1-+ni/XS5pE8kRzp+BnuUUa7bYROk=", + "dev": true + }, + "ipaddr.js": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", + "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", + "dev": true + }, + "is-absolute-url": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-2.1.0.tgz", + "integrity": "sha1-UFMN+4T8yap9vnhS6Do3uTufKqY=", + "dev": true + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arguments": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-arguments/-/is-arguments-1.0.4.tgz", + "integrity": "sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==", + "dev": true + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true + }, + "is-callable": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.0.tgz", + "integrity": "sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==", + "dev": true + }, + "is-color-stop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-color-stop/-/is-color-stop-1.1.0.tgz", + "integrity": "sha1-z/9HGu5N1cnhWFmPvhKWe1za00U=", + "dev": true, + "requires": { + "css-color-names": "^0.0.4", + "hex-color-regex": "^1.1.0", + "hsl-regex": "^1.0.0", + "hsla-regex": "^1.0.0", + "rgb-regex": "^1.0.1", + "rgba-regex": "^1.0.0" + } + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.2.tgz", + "integrity": "sha512-USlDT524woQ08aoZFzh3/Z6ch9Y/EWXEHQ/AaRN0SkKq4t2Jw2R2339tSXmwuVoY7LLlBCbOIlx2myP/L5zk0g==", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true + } + } + }, + "is-directory": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/is-directory/-/is-directory-0.3.1.tgz", + "integrity": "sha1-YTObbyR1/Hcv2cnYP1yFddwVSuE=", + "dev": true + }, + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "requires": { + "is-plain-object": "^2.0.4" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz", + "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==", + "dev": true + }, + "is-path-cwd": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz", + "integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==", + "dev": true + }, + "is-path-in-cwd": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-in-cwd/-/is-path-in-cwd-2.1.0.tgz", + "integrity": "sha512-rNocXHgipO+rvnP6dk3zI20RpOtrAM/kzbB258Uw5BWr3TpXi861yzjo16Dn4hUox07iw5AyeMLHWsujkjzvRQ==", + "dev": true, + "requires": { + "is-path-inside": "^2.1.0" + } + }, + "is-path-inside": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-2.1.0.tgz", + "integrity": "sha512-wiyhTzfDWsvwAW53OBWF5zuvaOGlZ6PwYxAbPVDhpm+gM09xKQGjBq/8uYN12aDvMxnAnq3dxTyoSoRNmg5YFg==", + "dev": true, + "requires": { + "path-is-inside": "^1.0.2" + } + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.0.tgz", + "integrity": "sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-resolvable": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-resolvable/-/is-resolvable-1.1.0.tgz", + "integrity": "sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg==", + "dev": true + }, + "is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", + "dev": true + }, + "is-svg": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-svg/-/is-svg-3.0.0.tgz", + "integrity": "sha512-gi4iHK53LR2ujhLVVj+37Ykh9GLqYHX6JOVXbLAucaG/Cqw9xwdFOjDM2qeifLs1sF1npXXFvDu0r5HNgCMrzQ==", + "dev": true, + "requires": { + "html-comment-regex": "^1.1.0" + } + }, + "is-symbol": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.3.tgz", + "integrity": "sha512-OwijhaRSgqvhm/0ZdAcXNZt9lYdKFpcRDT5ULUuYXPoT794UNOdU+gpT6Rzo7b4V2HUl/op6GqY894AZwv9faQ==", + "dev": true, + "requires": { + "has-symbols": "^1.0.1" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "is-wsl": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", + "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true + }, + "jest-worker": { + "version": "25.5.0", + "resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-25.5.0.tgz", + "integrity": "sha512-/dsSmUkIy5EBGfv/IjjqmFxrNAUpBERfGs1oHROyD7yxjG/w+t0GOJDX8O1k32ySmd7+a5IhnJU2qQFcJ4n1vw==", + "dev": true, + "requires": { + "merge-stream": "^2.0.0", + "supports-color": "^7.0.0" + }, + "dependencies": { + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.1.0.tgz", + "integrity": "sha512-oRSIpR8pxT1Wr2FquTNnGet79b3BWljqOuoW/h4oBhxJ/HUbX5nX6JSruTkvXDCFMwDPvsaTTbvMLKZWSy0R5g==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "jquery": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz", + "integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==" + }, + "jquery-ui": { + "version": "1.12.1", + "resolved": "https://registry.npmjs.org/jquery-ui/-/jquery-ui-1.12.1.tgz", + "integrity": "sha1-vLQEXI3QU5wTS8FIjN0+dop6nlE=" + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.0.tgz", + "integrity": "sha512-/4IbIeHcD9VMHFqDR/gQ7EdZdLimOvW2DdcxFjdyyZ9NsbS+ccrXqVWDtab/lRl5AlUqmpBx8EhPaWR+OtY17A==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + }, + "dependencies": { + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + } + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-parse-better-errors": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", + "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json3": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/json3/-/json3-3.3.3.tgz", + "integrity": "sha512-c7/8mbUsKigAbLkD5B010BK4D9LZm7A1pNItkEwiUZRpIN66exu/e7YQWysGun+TRKaJp8MhemM+VkfWv42aCA==", + "dev": true + }, + "json5": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.3.tgz", + "integrity": "sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "jsonfile": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz", + "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.6" + } + }, + "killable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/killable/-/killable-1.0.1.tgz", + "integrity": "sha512-LzqtLKlUwirEUyl/nicirVmNiPvYs7l5n8wOPP7fyJVpUPkvCnW/vuiXGpylGUlnPDnB7311rARzAt3Mhswpjg==", + "dev": true + }, + "kind-of": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", + "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==", + "dev": true + }, + "laravel-mix": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/laravel-mix/-/laravel-mix-5.0.4.tgz", + "integrity": "sha512-/fkcMdlxhGDBcH+kFDqKONlAfhJinMAWd+fjQ+VLii4UzIeXUF5Q8FbS4+ZrZs9JO3Y1E4KoNq3hMw0t/soahA==", + "dev": true, + "requires": { + "@babel/core": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-dynamic-import": "^7.2.0", + "@babel/plugin-transform-runtime": "^7.2.0", + "@babel/preset-env": "^7.2.0", + "@babel/runtime": "^7.2.0", + "autoprefixer": "^9.4.2", + "babel-loader": "^8.0.4", + "babel-merge": "^2.0.1", + "chokidar": "^2.0.3", + "clean-css": "^4.1.3", + "collect.js": "^4.12.8", + "concatenate": "0.0.2", + "css-loader": "^1.0.1", + "dotenv": "^6.2.0", + "dotenv-expand": "^4.2.0", + "extract-text-webpack-plugin": "v4.0.0-beta.0", + "file-loader": "^2.0.0", + "friendly-errors-webpack-plugin": "^1.6.1", + "fs-extra": "^7.0.1", + "glob": "^7.1.2", + "html-loader": "^0.5.5", + "imagemin": "^6.0.0", + "img-loader": "^3.0.0", + "lodash": "^4.17.15", + "md5": "^2.2.1", + "optimize-css-assets-webpack-plugin": "^5.0.1", + "postcss-loader": "^3.0.0", + "style-loader": "^0.23.1", + "terser": "^3.11.0", + "terser-webpack-plugin": "^2.2.3", + "vue-loader": "^15.4.2", + "webpack": "^4.36.1", + "webpack-cli": "^3.1.2", + "webpack-dev-server": "^3.1.14", + "webpack-merge": "^4.1.0", + "webpack-notifier": "^1.5.1", + "yargs": "^12.0.5" + } + }, + "laravel-mix-bundle-analyzer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/laravel-mix-bundle-analyzer/-/laravel-mix-bundle-analyzer-1.0.5.tgz", + "integrity": "sha512-Oeq1mW6oDaZZhjs1Yga/xZpj5kfH2TonKbqzSPW5BJiI8WomvMBGUmq9yHzy/Zh2fw0R/133U9/hFANTTrgjfQ==", + "dev": true, + "requires": { + "webpack-bundle-analyzer": "^3.0.3" + } + }, + "last-call-webpack-plugin": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/last-call-webpack-plugin/-/last-call-webpack-plugin-3.0.0.tgz", + "integrity": "sha512-7KI2l2GIZa9p2spzPIVZBYyNKkN+e/SQPpnjlTiPhdbDW3F86tdKKELxKpzJ5sgU19wQWsACULZmpTPYHeWO5w==", + "dev": true, + "requires": { + "lodash": "^4.17.5", + "webpack-sources": "^1.1.0" + } + }, + "lcid": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", + "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", + "dev": true, + "requires": { + "invert-kv": "^2.0.0" + } + }, + "leven": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz", + "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==", + "dev": true + }, + "levenary": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/levenary/-/levenary-1.1.1.tgz", + "integrity": "sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ==", + "dev": true, + "requires": { + "leven": "^3.1.0" + } + }, + "loader-runner": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", + "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", + "dev": true + }, + "loader-utils": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.0.tgz", + "integrity": "sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^3.0.0", + "json5": "^1.0.1" + }, + "dependencies": { + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + } + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.15", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", + "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==", + "dev": true + }, + "lodash.memoize": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz", + "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=", + "dev": true + }, + "lodash.uniq": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz", + "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=", + "dev": true + }, + "loglevel": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/loglevel/-/loglevel-1.6.8.tgz", + "integrity": "sha512-bsU7+gc9AJ2SqpzxwU3+1fedl8zAntbtC5XYlt3s2j1hJcn2PsXSmgN8TaLG/J1/2mod4+cE/3vNL70/c1RNCA==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "lower-case": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", + "integrity": "sha1-miyr0bno4K6ZOkv31YdcOcQujqw=", + "dev": true + }, + "lru-cache": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "dev": true, + "requires": { + "yallist": "^3.0.2" + }, + "dependencies": { + "yallist": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==", + "dev": true + } + } + }, + "make-dir": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", + "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", + "dev": true, + "requires": { + "pify": "^4.0.1", + "semver": "^5.6.0" + } + }, + "map-age-cleaner": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", + "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", + "dev": true, + "requires": { + "p-defer": "^1.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "md5": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/md5/-/md5-2.2.1.tgz", + "integrity": "sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=", + "dev": true, + "requires": { + "charenc": "~0.0.1", + "crypt": "~0.0.1", + "is-buffer": "~1.1.1" + } + }, + "md5.js": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", + "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1", + "safe-buffer": "^5.1.2" + } + }, + "mdn-data": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.4.tgz", + "integrity": "sha512-iV3XNKw06j5Q7mi6h+9vbx23Tv7JkjEVgKHW4pimwyDGWm0OIQntJJ+u1C6mg6mK1EaTv42XQ7w76yuzH7M2cA==", + "dev": true + }, + "media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g=", + "dev": true + }, + "mem": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", + "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", + "dev": true, + "requires": { + "map-age-cleaner": "^0.1.1", + "mimic-fn": "^2.0.0", + "p-is-promise": "^2.0.0" + } + }, + "memory-fs": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", + "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", + "dev": true, + "requires": { + "errno": "^0.1.3", + "readable-stream": "^2.0.1" + } + }, + "merge-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz", + "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E=", + "dev": true + }, + "merge-source-map": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/merge-source-map/-/merge-source-map-1.1.0.tgz", + "integrity": "sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw==", + "dev": true, + "requires": { + "source-map": "^0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==", + "dev": true + }, + "merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "dev": true + }, + "methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4=", + "dev": true + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "miller-rabin": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", + "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", + "dev": true, + "requires": { + "bn.js": "^4.0.0", + "brorand": "^1.0.1" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "mime": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", + "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", + "dev": true + }, + "mime-db": { + "version": "1.44.0", + "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.44.0.tgz", + "integrity": "sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==", + "dev": true + }, + "mime-types": { + "version": "2.1.27", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.27.tgz", + "integrity": "sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==", + "dev": true, + "requires": { + "mime-db": "1.44.0" + } + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "minimalistic-assert": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", + "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", + "dev": true + }, + "minimalistic-crypto-utils": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", + "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.5.tgz", + "integrity": "sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==", + "dev": true + }, + "minipass": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-3.1.3.tgz", + "integrity": "sha512-Mgd2GdMVzY+x3IJ+oHnVM+KG3lA5c8tnabyJKmHSaG2kAGpudxuOf8ToDkhumF7UzME7DecbQE9uOZhNm7PuJg==", + "dev": true, + "requires": { + "yallist": "^4.0.0" + } + }, + "minipass-collect": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/minipass-collect/-/minipass-collect-1.0.2.tgz", + "integrity": "sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-flush": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/minipass-flush/-/minipass-flush-1.0.5.tgz", + "integrity": "sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "minipass-pipeline": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/minipass-pipeline/-/minipass-pipeline-1.2.3.tgz", + "integrity": "sha512-cFOknTvng5vqnwOpDsZTWhNll6Jf8o2x+/diplafmxpuIymAjzoOolZG0VvQf3V2HgqzJNhnuKHYp2BqDgz8IQ==", + "dev": true, + "requires": { + "minipass": "^3.0.0" + } + }, + "mississippi": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", + "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", + "dev": true, + "requires": { + "concat-stream": "^1.5.0", + "duplexify": "^3.4.2", + "end-of-stream": "^1.1.0", + "flush-write-stream": "^1.0.0", + "from2": "^2.1.0", + "parallel-transform": "^1.1.0", + "pump": "^3.0.0", + "pumpify": "^1.3.3", + "stream-each": "^1.1.0", + "through2": "^2.0.0" + } + }, + "mixin-deep": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", + "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", + "dev": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + } + }, + "mkdirp": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", + "integrity": "sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5" + } + }, + "moment": { + "version": "2.26.0", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.26.0.tgz", + "integrity": "sha512-oIixUO+OamkUkwjhAVE18rAMfRJNsNe/Stid/gwHSOfHrOtw9EhAY2AHvdKZ/k/MggcYELFCJz/Sn2pL8b8JMw==" + }, + "move-concurrently": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", + "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", + "dev": true, + "requires": { + "aproba": "^1.1.1", + "copy-concurrently": "^1.0.0", + "fs-write-stream-atomic": "^1.0.8", + "mkdirp": "^0.5.1", + "rimraf": "^2.5.4", + "run-queue": "^1.0.3" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "multicast-dns": { + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/multicast-dns/-/multicast-dns-6.2.3.tgz", + "integrity": "sha512-ji6J5enbMyGRHIAkAOu3WdV8nggqviKCEKtXcOqfphZZtQrmHKycfynJ2V7eVPUA4NhJ6V7Wf4TmGbTwKE9B6g==", + "dev": true, + "requires": { + "dns-packet": "^1.3.1", + "thunky": "^1.0.2" + } + }, + "multicast-dns-service-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/multicast-dns-service-types/-/multicast-dns-service-types-1.1.0.tgz", + "integrity": "sha1-iZ8R2WhuXgXLkbNdXw5jt3PPyQE=", + "dev": true + }, + "nan": { + "version": "2.14.1", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.1.tgz", + "integrity": "sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "negotiator": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", + "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", + "dev": true + }, + "neo-async": { + "version": "2.6.1", + "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", + "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", + "dev": true + }, + "next-tick": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.0.0.tgz", + "integrity": "sha1-yobR/ogoFpsBICCOPchCS524NCw=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "no-case": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", + "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", + "dev": true, + "requires": { + "lower-case": "^1.1.1" + } + }, + "node-forge": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-0.9.0.tgz", + "integrity": "sha512-7ASaDa3pD+lJ3WvXFsxekJQelBKRpne+GOVbLbtHYdd7pFspyeuJHnWfLplGf3SwKGbfs/aYl5V/JCIaHVUKKQ==", + "dev": true + }, + "node-libs-browser": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", + "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", + "dev": true, + "requires": { + "assert": "^1.1.1", + "browserify-zlib": "^0.2.0", + "buffer": "^4.3.0", + "console-browserify": "^1.1.0", + "constants-browserify": "^1.0.0", + "crypto-browserify": "^3.11.0", + "domain-browser": "^1.1.1", + "events": "^3.0.0", + "https-browserify": "^1.0.0", + "os-browserify": "^0.3.0", + "path-browserify": "0.0.1", + "process": "^0.11.10", + "punycode": "^1.2.4", + "querystring-es3": "^0.2.0", + "readable-stream": "^2.3.3", + "stream-browserify": "^2.0.1", + "stream-http": "^2.7.2", + "string_decoder": "^1.0.0", + "timers-browserify": "^2.0.4", + "tty-browserify": "0.0.0", + "url": "^0.11.0", + "util": "^0.11.0", + "vm-browserify": "^1.0.1" + }, + "dependencies": { + "punycode": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", + "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", + "dev": true + } + } + }, + "node-notifier": { + "version": "5.4.3", + "resolved": "https://registry.npmjs.org/node-notifier/-/node-notifier-5.4.3.tgz", + "integrity": "sha512-M4UBGcs4jeOK9CjTsYwkvH6/MzuUmGCyTW+kCY7uO+1ZVr0+FHGdPdIf5CCLqAaxnRrWidyoQlNkMIIVwbKB8Q==", + "dev": true, + "requires": { + "growly": "^1.3.0", + "is-wsl": "^1.1.0", + "semver": "^5.5.0", + "shellwords": "^0.1.1", + "which": "^1.3.0" + }, + "dependencies": { + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, + "node-releases": { + "version": "1.1.58", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.58.tgz", + "integrity": "sha512-NxBudgVKiRh/2aPWMgPR7bPTX0VPmGx5QBwCtdHitnqFE5/O8DeBXuIMH1nwNnw/aMo6AjOrpsHzfY3UbUJ7yg==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "normalize-range": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz", + "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=", + "dev": true + }, + "normalize-url": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-3.3.0.tgz", + "integrity": "sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg==", + "dev": true + }, + "npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", + "dev": true, + "requires": { + "path-key": "^2.0.0" + }, + "dependencies": { + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + } + } + }, + "nth-check": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", + "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "dev": true, + "requires": { + "boolbase": "~1.0.0" + } + }, + "num2fraction": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/num2fraction/-/num2fraction-1.2.2.tgz", + "integrity": "sha1-b2gragJ6Tp3fpFZM0lidHU5mnt4=", + "dev": true + }, + "number-is-nan": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", + "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=", + "dev": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-inspect": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.7.0.tgz", + "integrity": "sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==", + "dev": true + }, + "object-is": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/object-is/-/object-is-1.1.2.tgz", + "integrity": "sha512-5lHCz+0uufF6wZ7CRFWJN3hp8Jqblpgve06U5CMQ3f//6iDjPr2PEo9MWCjEssDsa+UZEL4PkFpr+BMop6aKzQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-path": { + "version": "0.11.4", + "resolved": "https://registry.npmjs.org/object-path/-/object-path-0.11.4.tgz", + "integrity": "sha1-NwrnUvvzfePqcKhhwju6iRVpGUk=", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.getownpropertydescriptors": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.1.0.tgz", + "integrity": "sha512-Z53Oah9A3TdLoblT7VKJaTDdXdT+lQO+cNpKVnya5JDe9uLvzu1YyY1yFDFrcxrlRgWrEFH0jJtD/IbuwjcEVg==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "object.omit": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/object.omit/-/object.omit-3.0.0.tgz", + "integrity": "sha512-EO+BCv6LJfu+gBIF3ggLicFebFLN5zqzz/WWJlMFfkMyGth+oBkhxzDl0wx2W4GkLzuQs/FsSkXZb2IMWQqmBQ==", + "dev": true, + "requires": { + "is-extendable": "^1.0.0" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "object.values": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.1.tgz", + "integrity": "sha512-WTa54g2K8iu0kmS/us18jEmdv1a4Wi//BZ/DTVYEcH0XhLM5NYdpDHja3gt57VrZLcNAO2WGA+KpWsDBaHt6eA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "obuf": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz", + "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", + "dev": true + }, + "on-finished": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz", + "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=", + "dev": true, + "requires": { + "ee-first": "1.1.1" + } + }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "opener": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.1.tgz", + "integrity": "sha512-goYSy5c2UXE4Ra1xixabeVh1guIX/ZV/YokJksb6q2lubWu6UbvPQ20p542/sFIll1nl8JnCyK9oBaOcCWXwvA==", + "dev": true + }, + "opn": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/opn/-/opn-5.5.0.tgz", + "integrity": "sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==", + "dev": true, + "requires": { + "is-wsl": "^1.1.0" + } + }, + "optimize-css-assets-webpack-plugin": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/optimize-css-assets-webpack-plugin/-/optimize-css-assets-webpack-plugin-5.0.3.tgz", + "integrity": "sha512-q9fbvCRS6EYtUKKSwI87qm2IxlyJK5b4dygW1rKUBT6mMDhdG5e5bZT63v6tnJR9F9FB/H5a0HTmtw+laUBxKA==", + "dev": true, + "requires": { + "cssnano": "^4.1.10", + "last-call-webpack-plugin": "^3.0.0" + } + }, + "original": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/original/-/original-1.0.2.tgz", + "integrity": "sha512-hyBVl6iqqUOJ8FqRe+l/gS8H+kKYjrEndd5Pm1MfBtsEKA038HkkdbAl/72EAXGyonD/PFsvmVG+EvcIpliMBg==", + "dev": true, + "requires": { + "url-parse": "^1.4.3" + } + }, + "os-browserify": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", + "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", + "dev": true + }, + "os-locale": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", + "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", + "dev": true, + "requires": { + "execa": "^1.0.0", + "lcid": "^2.0.0", + "mem": "^4.0.0" + } + }, + "overlayscrollbars": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/overlayscrollbars/-/overlayscrollbars-1.12.0.tgz", + "integrity": "sha512-zJGYLeBfaPx2VmiDfBMNTPzm9N8w8wZ6M7dm1ee8TGuet8tsK4nxOzGvEEu0SmueqMHQxhLsstf7iTWCGiYa9Q==" + }, + "p-defer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", + "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", + "dev": true + }, + "p-finally": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", + "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", + "dev": true + }, + "p-is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", + "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", + "dev": true + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-map": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-map/-/p-map-3.0.0.tgz", + "integrity": "sha512-d3qXVTF/s+W+CdJ5A29wywV2n8CQQYahlgz2bFiA+4eVNJbHJodPZ+/gXwPGh0bOqA+j8S+6+ckmvLGPk1QpxQ==", + "dev": true, + "requires": { + "aggregate-error": "^3.0.0" + } + }, + "p-pipe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/p-pipe/-/p-pipe-1.2.0.tgz", + "integrity": "sha1-SxoROZoRUgpneQ7loMHViB1r7+k=", + "dev": true + }, + "p-retry": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/p-retry/-/p-retry-3.0.1.tgz", + "integrity": "sha512-XE6G4+YTTkT2a0UWb2kjZe8xNwf8bIbnqpc/IS/idOBVhyves0mK5OJgeocjx7q5pvX/6m23xuzVPYT1uGM73w==", + "dev": true, + "requires": { + "retry": "^0.12.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "pako": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz", + "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==", + "dev": true + }, + "parallel-transform": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.2.0.tgz", + "integrity": "sha512-P2vSmIu38uIlvdcU7fDkyrxj33gTUy/ABO5ZUbGowxNCopBq/OoD42bP4UmMrJoPyk4Uqf0mu3mtWBhHCZD8yg==", + "dev": true, + "requires": { + "cyclist": "^1.0.1", + "inherits": "^2.0.3", + "readable-stream": "^2.1.5" + } + }, + "param-case": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", + "integrity": "sha1-35T9jPZTHs915r75oIWPvHK+Ikc=", + "dev": true, + "requires": { + "no-case": "^2.2.0" + } + }, + "parse-asn1": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.5.tgz", + "integrity": "sha512-jkMYn1dcJqF6d5CpU689bq7w/b5ALS9ROVSpQDPrZsqqesUJii9qutvoT5ltGedNXMO2e16YUWIghG9KxaViTQ==", + "dev": true, + "requires": { + "asn1.js": "^4.0.0", + "browserify-aes": "^1.0.0", + "create-hash": "^1.1.0", + "evp_bytestokey": "^1.0.0", + "pbkdf2": "^3.0.3", + "safe-buffer": "^5.1.1" + } + }, + "parse-json": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-4.0.0.tgz", + "integrity": "sha1-vjX1Qlvh9/bHRxhPmKeIy5lHfuA=", + "dev": true, + "requires": { + "error-ex": "^1.3.1", + "json-parse-better-errors": "^1.0.1" + } + }, + "parse-passwd": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", + "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", + "dev": true + }, + "parseurl": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", + "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", + "dev": true + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true + }, + "path-browserify": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", + "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", + "dev": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-to-regexp": { + "version": "0.1.7", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", + "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w=", + "dev": true + }, + "path-type": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-3.0.0.tgz", + "integrity": "sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==", + "dev": true, + "requires": { + "pify": "^3.0.0" + }, + "dependencies": { + "pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", + "dev": true + } + } + }, + "pbkdf2": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.1.1.tgz", + "integrity": "sha512-4Ejy1OPxi9f2tt1rRV7Go7zmfDQ+ZectEQz3VGUQhgq62HtIRPDyG/JtnwIxs6x3uNMwo2V7q1fMvKjb+Tnpqg==", + "dev": true, + "requires": { + "create-hash": "^1.1.2", + "create-hmac": "^1.1.4", + "ripemd160": "^2.0.1", + "safe-buffer": "^5.0.1", + "sha.js": "^2.4.8" + } + }, + "picomatch": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz", + "integrity": "sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg==", + "dev": true, + "optional": true + }, + "pify": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", + "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", + "dev": true + }, + "pinkie": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/pinkie/-/pinkie-2.0.4.tgz", + "integrity": "sha1-clVrgM+g1IqXToDnckjoDtT3+HA=", + "dev": true + }, + "pinkie-promise": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pinkie-promise/-/pinkie-promise-2.0.1.tgz", + "integrity": "sha1-ITXW36ejWMBprJsXh3YogihFD/o=", + "dev": true, + "requires": { + "pinkie": "^2.0.0" + } + }, + "pkg-dir": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", + "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", + "dev": true, + "requires": { + "find-up": "^3.0.0" + }, + "dependencies": { + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + } + } + }, + "pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-up/-/pkg-up-2.0.0.tgz", + "integrity": "sha1-yBmscoBZpGHKscOImivjxJoATX8=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "popper.js": { + "version": "1.16.1", + "resolved": "https://registry.npmjs.org/popper.js/-/popper.js-1.16.1.tgz", + "integrity": "sha512-Wb4p1J4zyFTbM+u6WuO4XstYx4Ky9Cewe4DWrel7B0w6VVICvPwdOpotjzcf6eD8TsckVnIMNONQyPIUFOUbCQ==" + }, + "portfinder": { + "version": "1.0.26", + "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.26.tgz", + "integrity": "sha512-Xi7mKxJHHMI3rIUrnm/jjUgwhbYMkp/XKEcZX3aG4BrumLpq3nmoQMX+ClYnDZnZ/New7IatC1no5RX0zo1vXQ==", + "dev": true, + "requires": { + "async": "^2.6.2", + "debug": "^3.1.1", + "mkdirp": "^0.5.1" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true + }, + "postcss": { + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "postcss-calc": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/postcss-calc/-/postcss-calc-7.0.2.tgz", + "integrity": "sha512-rofZFHUg6ZIrvRwPeFktv06GdbDYLcGqh9EwiMutZg+a0oePCCw1zHOEiji6LCpyRcjTREtPASuUqeAvYlEVvQ==", + "dev": true, + "requires": { + "postcss": "^7.0.27", + "postcss-selector-parser": "^6.0.2", + "postcss-value-parser": "^4.0.2" + } + }, + "postcss-colormin": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-colormin/-/postcss-colormin-4.0.3.tgz", + "integrity": "sha512-WyQFAdDZpExQh32j0U0feWisZ0dmOtPl44qYmJKkq9xFWY3p+4qnRzCHeNrkeRhwPHz9bQ3mo0/yVkaply0MNw==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "color": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-convert-values": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-convert-values/-/postcss-convert-values-4.0.1.tgz", + "integrity": "sha512-Kisdo1y77KUC0Jmn0OXU/COOJbzM8cImvw1ZFsBgBgMgb1iL23Zs/LXRe3r+EZqM3vGYKdQ2YJVQ5VkJI+zEJQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-discard-comments": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-comments/-/postcss-discard-comments-4.0.2.tgz", + "integrity": "sha512-RJutN259iuRf3IW7GZyLM5Sw4GLTOH8FmsXBnv8Ab/Tc2k4SR4qbV4DNbyyY4+Sjo362SyDmW2DQ7lBSChrpkg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-duplicates": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-discard-duplicates/-/postcss-discard-duplicates-4.0.2.tgz", + "integrity": "sha512-ZNQfR1gPNAiXZhgENFfEglF93pciw0WxMkJeVmw8eF+JZBbMD7jp6C67GqJAXVZP2BWbOztKfbsdmMp/k8c6oQ==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-empty": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-empty/-/postcss-discard-empty-4.0.1.tgz", + "integrity": "sha512-B9miTzbznhDjTfjvipfHoqbWKwd0Mj+/fL5s1QOz06wufguil+Xheo4XpOnc4NqKYBCNqqEzgPv2aPBIJLox0w==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-discard-overridden": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-discard-overridden/-/postcss-discard-overridden-4.0.1.tgz", + "integrity": "sha512-IYY2bEDD7g1XM1IDEsUT4//iEYCxAmP5oDSFMVU/JVvT7gh+l4fmjciLqGgwjdWpQIdb0Che2VX00QObS5+cTg==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-load-config": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-2.1.0.tgz", + "integrity": "sha512-4pV3JJVPLd5+RueiVVB+gFOAa7GWc25XQcMp86Zexzke69mKf6Nx9LRcQywdz7yZI9n1udOxmLuAwTBypypF8Q==", + "dev": true, + "requires": { + "cosmiconfig": "^5.0.0", + "import-cwd": "^2.0.0" + } + }, + "postcss-loader": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/postcss-loader/-/postcss-loader-3.0.0.tgz", + "integrity": "sha512-cLWoDEY5OwHcAjDnkyRQzAXfs2jrKjXpO/HQFcc5b5u/r7aa471wdmChmwfnv7x2u840iat/wi0lQ5nbRgSkUA==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "postcss": "^7.0.0", + "postcss-load-config": "^2.0.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "postcss-merge-longhand": { + "version": "4.0.11", + "resolved": "https://registry.npmjs.org/postcss-merge-longhand/-/postcss-merge-longhand-4.0.11.tgz", + "integrity": "sha512-alx/zmoeXvJjp7L4mxEMjh8lxVlDFX1gqWHzaaQewwMZiVhLo42TEClKaeHbRf6J7j82ZOdTJ808RtN0ZOZwvw==", + "dev": true, + "requires": { + "css-color-names": "0.0.4", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "stylehacks": "^4.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-merge-rules": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-merge-rules/-/postcss-merge-rules-4.0.3.tgz", + "integrity": "sha512-U7e3r1SbvYzO0Jr3UT/zKBVgYYyhAz0aitvGIYOYK5CPmkNih+WDSsS5tvPrJ8YMQYlEMvsZIiqmn7HdFUaeEQ==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "cssnano-util-same-parent": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0", + "vendors": "^1.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-minify-font-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-font-values/-/postcss-minify-font-values-4.0.2.tgz", + "integrity": "sha512-j85oO6OnRU9zPf04+PZv1LYIYOprWm6IA6zkXkrJXyRveDEuQggG6tvoy8ir8ZwjLxLuGfNkCZEQG7zan+Hbtg==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-gradients": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-gradients/-/postcss-minify-gradients-4.0.2.tgz", + "integrity": "sha512-qKPfwlONdcf/AndP1U8SJ/uzIJtowHlMaSioKzebAXSG4iJthlWC9iSWznQcX4f66gIWX44RSA841HTHj3wK+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "is-color-stop": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-params": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-params/-/postcss-minify-params-4.0.2.tgz", + "integrity": "sha512-G7eWyzEx0xL4/wiBBJxJOz48zAKV2WG3iZOqVhPet/9geefm/Px5uo1fzlHu+DOjT+m0Mmiz3jkQzVHe6wxAWg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "browserslist": "^4.0.0", + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "uniqs": "^2.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-minify-selectors": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-minify-selectors/-/postcss-minify-selectors-4.0.2.tgz", + "integrity": "sha512-D5S1iViljXBj9kflQo4YutWnJmwm8VvIsU1GeXJGiG9j8CIg9zs4voPMdQDUmIxetUOh60VilsNzCiAFTOqu3g==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "postcss-modules-extract-imports": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/postcss-modules-extract-imports/-/postcss-modules-extract-imports-1.2.1.tgz", + "integrity": "sha512-6jt9XZwUhwmRUhb/CkyJY020PYaPJsCyt3UjbaWo6XEbH/94Hmv6MP7fG2C5NDU/BcHzyGYxNtHvM+LTf9HrYw==", + "dev": true, + "requires": { + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-modules-local-by-default": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz", + "integrity": "sha1-99gMOYxaOT+nlkRmvRlQCn1hwGk=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-modules-scope": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz", + "integrity": "sha1-1upkmUx5+XtipytCb75gVqGUu5A=", + "dev": true, + "requires": { + "css-selector-tokenizer": "^0.7.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-modules-values": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz", + "integrity": "sha1-7P+p1+GSUYOJ9CrQ6D9yrsRW6iA=", + "dev": true, + "requires": { + "icss-replace-symbols": "^1.1.0", + "postcss": "^6.0.1" + }, + "dependencies": { + "postcss": { + "version": "6.0.23", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-6.0.23.tgz", + "integrity": "sha512-soOk1h6J3VMTZtVeVpv15/Hpdl2cBLX3CAw4TAbkpTJiNPk9YP/zWcD1ND+xEtvyuuvKzbxliTOIyvkSeSJ6ag==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "source-map": "^0.6.1", + "supports-color": "^5.4.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "postcss-normalize-charset": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-charset/-/postcss-normalize-charset-4.0.1.tgz", + "integrity": "sha512-gMXCrrlWh6G27U0hF3vNvR3w8I1s2wOBILvA87iNXaPvSNo5uZAMYsZG7XjCUf1eVxuPfyL4TJ7++SGZLc9A3g==", + "dev": true, + "requires": { + "postcss": "^7.0.0" + } + }, + "postcss-normalize-display-values": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-display-values/-/postcss-normalize-display-values-4.0.2.tgz", + "integrity": "sha512-3F2jcsaMW7+VtRMAqf/3m4cPFhPD3EFRgNs18u+k3lTJJlVe7d0YPO+bnwqo2xg8YiRpDXJI2u8A0wqJxMsQuQ==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-positions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-positions/-/postcss-normalize-positions-4.0.2.tgz", + "integrity": "sha512-Dlf3/9AxpxE+NF1fJxYDeggi5WwV35MXGFnnoccP/9qDtFrTArZ0D0R+iKcg5WsUd8nUYMIl8yXDCtcrT8JrdA==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-repeat-style": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-repeat-style/-/postcss-normalize-repeat-style-4.0.2.tgz", + "integrity": "sha512-qvigdYYMpSuoFs3Is/f5nHdRLJN/ITA7huIoCyqqENJe9PvPmLhNLMu7QTjPdtnVf6OcYYO5SHonx4+fbJE1+Q==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-string": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-string/-/postcss-normalize-string-4.0.2.tgz", + "integrity": "sha512-RrERod97Dnwqq49WNz8qo66ps0swYZDSb6rM57kN2J+aoyEAJfZ6bMx0sx/F9TIEX0xthPGCmeyiam/jXif0eA==", + "dev": true, + "requires": { + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-timing-functions": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-timing-functions/-/postcss-normalize-timing-functions-4.0.2.tgz", + "integrity": "sha512-acwJY95edP762e++00Ehq9L4sZCEcOPyaHwoaFOhIwWCDfik6YvqsYNxckee65JHLKzuNSSmAdxwD2Cud1Z54A==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-unicode": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-unicode/-/postcss-normalize-unicode-4.0.1.tgz", + "integrity": "sha512-od18Uq2wCYn+vZ/qCOeutvHjB5jm57ToxRaMeNuf0nWVHaP9Hua56QyMF6fs/4FSUnVIw0CBPsU0K4LnBPwYwg==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-url": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-normalize-url/-/postcss-normalize-url-4.0.1.tgz", + "integrity": "sha512-p5oVaF4+IHwu7VpMan/SSpmpYxcJMtkGppYf0VbdH5B6hN8YNmVyJLuY9FmLQTzY3fag5ESUUHDqM+heid0UVA==", + "dev": true, + "requires": { + "is-absolute-url": "^2.0.0", + "normalize-url": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-normalize-whitespace": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-normalize-whitespace/-/postcss-normalize-whitespace-4.0.2.tgz", + "integrity": "sha512-tO8QIgrsI3p95r8fyqKV+ufKlSHh9hMJqACqbv2XknufqEDhDvbguXGBBqxw9nsQoXWf0qOqppziKJKHMD4GtA==", + "dev": true, + "requires": { + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-ordered-values": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/postcss-ordered-values/-/postcss-ordered-values-4.1.2.tgz", + "integrity": "sha512-2fCObh5UanxvSxeXrtLtlwVThBvHn6MQcu4ksNT2tsaV2Fg76R2CV98W7wNSlX+5/pFwEyaDwKLLoEV7uRybAw==", + "dev": true, + "requires": { + "cssnano-util-get-arguments": "^4.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-reduce-initial": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/postcss-reduce-initial/-/postcss-reduce-initial-4.0.3.tgz", + "integrity": "sha512-gKWmR5aUulSjbzOfD9AlJiHCGH6AEVLaM0AV+aSioxUDd16qXP1PCh8d1/BGVvpdWn8k/HiK7n6TjeoXN1F7DA==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "caniuse-api": "^3.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0" + } + }, + "postcss-reduce-transforms": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-reduce-transforms/-/postcss-reduce-transforms-4.0.2.tgz", + "integrity": "sha512-EEVig1Q2QJ4ELpJXMZR8Vt5DQx8/mo+dGWSR7vWXqcob2gQLyQGsionYcGKATXvQzMPn6DSN1vTN7yFximdIAg==", + "dev": true, + "requires": { + "cssnano-util-get-match": "^4.0.0", + "has": "^1.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-selector-parser": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-6.0.2.tgz", + "integrity": "sha512-36P2QR59jDTOAiIkqEprfJDsoNrvwFei3eCqKd1Y0tUsBimsq39BLp7RD+JWny3WgB1zGhJX8XVePwm9k4wdBg==", + "dev": true, + "requires": { + "cssesc": "^3.0.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + }, + "postcss-svgo": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/postcss-svgo/-/postcss-svgo-4.0.2.tgz", + "integrity": "sha512-C6wyjo3VwFm0QgBy+Fu7gCYOkCmgmClghO+pjcxvrcBKtiKt0uCF+hvbMO1fyv5BMImRK90SMb+dwUnfbGd+jw==", + "dev": true, + "requires": { + "is-svg": "^3.0.0", + "postcss": "^7.0.0", + "postcss-value-parser": "^3.0.0", + "svgo": "^1.0.0" + }, + "dependencies": { + "postcss-value-parser": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-3.3.1.tgz", + "integrity": "sha512-pISE66AbVkp4fDQ7VHBwRNXzAAKJjw4Vw7nWI/+Q3vuly7SNfgYXvm6i5IgFylHGK5sP/xHAbB7N49OS4gWNyQ==", + "dev": true + } + } + }, + "postcss-unique-selectors": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/postcss-unique-selectors/-/postcss-unique-selectors-4.0.1.tgz", + "integrity": "sha512-+JanVaryLo9QwZjKrmJgkI4Fn8SBgRO6WXQBJi7KiAVPlmxikB5Jzc4EvXMT2H0/m0RjrVVm9rGNhZddm/8Spg==", + "dev": true, + "requires": { + "alphanum-sort": "^1.0.0", + "postcss": "^7.0.0", + "uniqs": "^2.0.0" + } + }, + "postcss-value-parser": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.1.0.tgz", + "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", + "dev": true + }, + "prettier": { + "version": "1.19.1", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.19.1.tgz", + "integrity": "sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==", + "dev": true, + "optional": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", + "dev": true + }, + "promise-inflight": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", + "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", + "dev": true + }, + "proxy-addr": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.6.tgz", + "integrity": "sha512-dh/frvCBVmSsDYzw6n926jv974gddhkFPfiN8hPOi30Wax25QZyZEGveluCgliBnqmuM+UJmBErbAUFIoDbjOw==", + "dev": true, + "requires": { + "forwarded": "~0.1.2", + "ipaddr.js": "1.9.1" + } + }, + "prr": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", + "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", + "dev": true + }, + "pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", + "dev": true + }, + "public-encrypt": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", + "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", + "dev": true, + "requires": { + "bn.js": "^4.1.0", + "browserify-rsa": "^4.0.0", + "create-hash": "^1.1.0", + "parse-asn1": "^5.0.0", + "randombytes": "^2.0.1", + "safe-buffer": "^5.1.2" + }, + "dependencies": { + "bn.js": { + "version": "4.11.9", + "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.9.tgz", + "integrity": "sha512-E6QoYqCKZfgatHTdHzs1RRKP7ip4vvm+EyRUeE2RF0NblwVvb0p6jSVeNTOFxPn26QXN2o6SMfNxKp6kU8zQaw==", + "dev": true + } + } + }, + "pump": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", + "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + }, + "pumpify": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", + "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", + "dev": true, + "requires": { + "duplexify": "^3.6.0", + "inherits": "^2.0.3", + "pump": "^2.0.0" + }, + "dependencies": { + "pump": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", + "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "once": "^1.3.1" + } + } + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "q": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", + "integrity": "sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc=", + "dev": true + }, + "qs": { + "version": "6.7.0", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.7.0.tgz", + "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", + "dev": true + }, + "querystring": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", + "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", + "dev": true + }, + "querystring-es3": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", + "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", + "dev": true + }, + "querystringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz", + "integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==", + "dev": true + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "randomfill": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", + "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", + "dev": true, + "requires": { + "randombytes": "^2.0.5", + "safe-buffer": "^5.1.0" + } + }, + "range-parser": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz", + "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==", + "dev": true + }, + "raw-body": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.4.0.tgz", + "integrity": "sha512-4Oz8DUIwdvoa5qMJelxipzi/iJIi40O5cGV1wNYp5hvZP8ZN0T+jiNkL0QepXs+EsQ9XJ8ipEDoiH70ySUJP3Q==", + "dev": true, + "requires": { + "bytes": "3.1.0", + "http-errors": "1.7.2", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "dependencies": { + "bytes": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.0.tgz", + "integrity": "sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==", + "dev": true + } + } + }, + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "dev": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "recast": { + "version": "0.11.23", + "resolved": "https://registry.npmjs.org/recast/-/recast-0.11.23.tgz", + "integrity": "sha1-RR/TAEqx5N+bTktmN2sqIZEkYtM=", + "dev": true, + "requires": { + "ast-types": "0.9.6", + "esprima": "~3.1.0", + "private": "~0.1.5", + "source-map": "~0.5.0" + } + }, + "regenerate": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", + "integrity": "sha512-j2+C8+NtXQgEKWk49MMP5P/u2GhnahTtVkRIHr5R5lVRlbKvmQ+oS+A5aLKWp2ma5VkT8sh6v+v4hbH0YHR66A==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.2.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz", + "integrity": "sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.5", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz", + "integrity": "sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.4", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.4.tgz", + "integrity": "sha512-EaJaKPBI9GvKpvUz2mz4fhx7WPgvwRLY9v3hlNHWmAuJHI13T4nwKnNvm5RWJzEdnI5g5UwtOww+S8IdoUC2bw==", + "dev": true, + "requires": { + "@babel/runtime": "^7.8.4", + "private": "^0.1.8" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regex-parser": { + "version": "2.2.10", + "resolved": "https://registry.npmjs.org/regex-parser/-/regex-parser-2.2.10.tgz", + "integrity": "sha512-8t6074A68gHfU8Neftl0Le6KTDwfGAj7IyjPIMSfikI2wJUTHDMaIq42bUsfVnj8mhx0R+45rdUXHGpN164avA==", + "dev": true + }, + "regexp.prototype.flags": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.3.0.tgz", + "integrity": "sha512-2+Q0C5g951OlYlJz6yu5/M33IcsESLlLfsyIaLJaG4FA2r4yP8MvVMJUUP/fVBkSpbbbZlS5gynbEWLipiiXiQ==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.0-next.1" + } + }, + "regexpu-core": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.7.0.tgz", + "integrity": "sha512-TQ4KXRnIn6tz6tjnrXEkD/sshygKH/j5KzK86X8MkeHyZ8qst/LZ89j3X4/8HEIfHANTFIP/AbXakeRhWIl5YQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.2.0", + "regjsgen": "^0.5.1", + "regjsparser": "^0.6.4", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.2.0" + } + }, + "regjsgen": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.2.tgz", + "integrity": "sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A==", + "dev": true + }, + "regjsparser": { + "version": "0.6.4", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.4.tgz", + "integrity": "sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "relateurl": { + "version": "0.2.7", + "resolved": "https://registry.npmjs.org/relateurl/-/relateurl-0.2.7.tgz", + "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true + }, + "replace-ext": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.1.tgz", + "integrity": "sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==", + "dev": true + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "require-main-filename": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", + "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", + "dev": true + }, + "requires-port": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", + "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=", + "dev": true + }, + "resolve": { + "version": "1.17.0", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", + "integrity": "sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-cwd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", + "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", + "dev": true, + "requires": { + "resolve-from": "^3.0.0" + } + }, + "resolve-dir": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", + "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", + "dev": true, + "requires": { + "expand-tilde": "^2.0.0", + "global-modules": "^1.0.0" + }, + "dependencies": { + "global-modules": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", + "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", + "dev": true, + "requires": { + "global-prefix": "^1.0.1", + "is-windows": "^1.0.1", + "resolve-dir": "^1.0.0" + } + } + } + }, + "resolve-from": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", + "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true + }, + "resolve-url-loader": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/resolve-url-loader/-/resolve-url-loader-3.1.1.tgz", + "integrity": "sha512-K1N5xUjj7v0l2j/3Sgs5b8CjrrgtC70SmdCuZiJ8tSyb5J+uk3FoeZ4b7yTnH6j7ngI+Bc5bldHJIa8hYdu2gQ==", + "dev": true, + "requires": { + "adjust-sourcemap-loader": "2.0.0", + "camelcase": "5.3.1", + "compose-function": "3.0.3", + "convert-source-map": "1.7.0", + "es6-iterator": "2.0.3", + "loader-utils": "1.2.3", + "postcss": "7.0.21", + "rework": "1.0.1", + "rework-visit": "1.0.0", + "source-map": "0.6.1" + }, + "dependencies": { + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "postcss": { + "version": "7.0.21", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.21.tgz", + "integrity": "sha512-uIFtJElxJo29QC753JzhidoAhvp/e/Exezkdhfmt8AymWT6/5B7W1WmponYWkHk2eg6sONyTch0A3nkMPun3SQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "source-map": "^0.6.1", + "supports-color": "^6.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + }, + "rework": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rework/-/rework-1.0.1.tgz", + "integrity": "sha1-MIBqhBNCtUUQqkEQhQzUhTQUSqc=", + "dev": true, + "requires": { + "convert-source-map": "^0.3.3", + "css": "^2.0.0" + }, + "dependencies": { + "convert-source-map": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-0.3.5.tgz", + "integrity": "sha1-8dgClQr33SYxof6+BZZVDIarMZA=", + "dev": true + } + } + }, + "rework-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rework-visit/-/rework-visit-1.0.0.tgz", + "integrity": "sha1-mUWygD8hni96ygCtuLyfZA+ELJo=", + "dev": true + }, + "rgb-regex": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/rgb-regex/-/rgb-regex-1.0.1.tgz", + "integrity": "sha1-wODWiC3w4jviVKR16O3UGRX+rrE=", + "dev": true + }, + "rgba-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/rgba-regex/-/rgba-regex-1.0.0.tgz", + "integrity": "sha1-QzdOLiyglosO8VI0YLfXMP8i7rM=", + "dev": true + }, + "rimraf": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "ripemd160": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", + "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", + "dev": true, + "requires": { + "hash-base": "^3.0.0", + "inherits": "^2.0.1" + } + }, + "run-queue": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", + "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", + "dev": true, + "requires": { + "aproba": "^1.1.1" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "sass": { + "version": "1.26.8", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.8.tgz", + "integrity": "sha512-yvtzyrKLGiXQu7H12ekXqsfoGT/aTKeMDyVzCB675k1HYuaj0py63i8Uf4SI9CHXj6apDhpfwbUr3gGOjdpu2Q==", + "dev": true, + "requires": { + "chokidar": ">=2.0.0 <4.0.0" + } + }, + "sass-loader": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/sass-loader/-/sass-loader-8.0.2.tgz", + "integrity": "sha512-7o4dbSK8/Ol2KflEmSco4jTjQoV988bM82P9CZdmo9hR3RLnvNc0ufMNdMrB0caq38JQ/FgF4/7RcbcfKzxoFQ==", + "dev": true, + "requires": { + "clone-deep": "^4.0.1", + "loader-utils": "^1.2.3", + "neo-async": "^2.6.1", + "schema-utils": "^2.6.1", + "semver": "^6.3.0" + }, + "dependencies": { + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + } + } + }, + "sax": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz", + "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==", + "dev": true + }, + "schema-utils": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-2.7.0.tgz", + "integrity": "sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A==", + "dev": true, + "requires": { + "@types/json-schema": "^7.0.4", + "ajv": "^6.12.2", + "ajv-keywords": "^3.4.1" + } + }, + "select-hose": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", + "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", + "dev": true + }, + "selfsigned": { + "version": "1.10.7", + "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-1.10.7.tgz", + "integrity": "sha512-8M3wBCzeWIJnQfl43IKwOmC4H/RAp50S8DF60znzjW5GVqTcSe2vWclt7hmYVPkKPlHWOu5EaWOMZ2Y6W8ZXTA==", + "dev": true, + "requires": { + "node-forge": "0.9.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "send": { + "version": "0.17.1", + "resolved": "https://registry.npmjs.org/send/-/send-0.17.1.tgz", + "integrity": "sha512-BsVKsiGcQMFwT8UxypobUKyv7irCNRHk1T0G680vk88yf6LBByGcZJOTJCrTP2xVN6yI+XjPJcNuE3V4fT9sAg==", + "dev": true, + "requires": { + "debug": "2.6.9", + "depd": "~1.1.2", + "destroy": "~1.0.4", + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "etag": "~1.8.1", + "fresh": "0.5.2", + "http-errors": "~1.7.2", + "mime": "1.6.0", + "ms": "2.1.1", + "on-finished": "~2.3.0", + "range-parser": "~1.2.1", + "statuses": "~1.5.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + }, + "dependencies": { + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + } + } + }, + "ms": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", + "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", + "dev": true + } + } + }, + "serialize-javascript": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-3.1.0.tgz", + "integrity": "sha512-JIJT1DGiWmIKhzRsG91aS6Ze4sFUrYbltlkg2onR5OrnNM02Kl/hnY/T4FN2omvyeBbQmMJv+K4cPOpGzOTFBg==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "serve-index": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/serve-index/-/serve-index-1.9.1.tgz", + "integrity": "sha1-03aNabHn2C5c4FD/9bRTvqEqkjk=", + "dev": true, + "requires": { + "accepts": "~1.3.4", + "batch": "0.6.1", + "debug": "2.6.9", + "escape-html": "~1.0.3", + "http-errors": "~1.6.2", + "mime-types": "~2.1.17", + "parseurl": "~1.3.2" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "http-errors": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.3.tgz", + "integrity": "sha1-i1VoC7S+KDoLW/TqLjhYC+HZMg0=", + "dev": true, + "requires": { + "depd": "~1.1.2", + "inherits": "2.0.3", + "setprototypeof": "1.1.0", + "statuses": ">= 1.4.0 < 2" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz", + "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ==", + "dev": true + } + } + }, + "serve-static": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.14.1.tgz", + "integrity": "sha512-JMrvUwE54emCYWlTI+hGrGv5I8dEwmco/00EvkzIIsR7MqrHonbD9pO2MOfFnpFntl7ecpZs+3mW+XbQZu9QCg==", + "dev": true, + "requires": { + "encodeurl": "~1.0.2", + "escape-html": "~1.0.3", + "parseurl": "~1.3.3", + "send": "0.17.1" + } + }, + "set-blocking": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", + "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", + "dev": true + }, + "set-value": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", + "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", + "dev": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "setimmediate": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", + "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", + "dev": true + }, + "setprototypeof": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.1.tgz", + "integrity": "sha512-JvdAWfbXeIGaZ9cILp38HntZSFSo3mWg6xGcJJsd+d4aRMOqauag1C63dJfDw7OaMYwEbHMOxEZ1lqVRYP2OAw==", + "dev": true + }, + "sha.js": { + "version": "2.4.11", + "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", + "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", + "dev": true, + "requires": { + "inherits": "^2.0.1", + "safe-buffer": "^5.0.1" + } + }, + "shallow-clone": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/shallow-clone/-/shallow-clone-3.0.1.tgz", + "integrity": "sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==", + "dev": true, + "requires": { + "kind-of": "^6.0.2" + } + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "shellwords": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz", + "integrity": "sha512-vFwSUfQvqybiICwZY5+DAWIPLKsWO31Q91JSKl3UYv+K5c2QRPzn0qzec6QPu1Qc9eHYItiP3NdJqNVqetYAww==", + "dev": true + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha1-pNprY1/8zMoz9w0Xy5JZLeleVXo=", + "dev": true, + "requires": { + "is-arrayish": "^0.3.1" + }, + "dependencies": { + "is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "dev": true + } + } + }, + "slash": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", + "dev": true + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "sockjs": { + "version": "0.3.20", + "resolved": "https://registry.npmjs.org/sockjs/-/sockjs-0.3.20.tgz", + "integrity": "sha512-SpmVOVpdq0DJc0qArhF3E5xsxvaiqGNb73XfgBpK1y3UD5gs8DSo8aCTsuT5pX8rssdc2NDIzANwP9eCAiSdTA==", + "dev": true, + "requires": { + "faye-websocket": "^0.10.0", + "uuid": "^3.4.0", + "websocket-driver": "0.6.5" + } + }, + "sockjs-client": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/sockjs-client/-/sockjs-client-1.4.0.tgz", + "integrity": "sha512-5zaLyO8/nri5cua0VtOrFXBPK1jbL4+1cebT/mmKA1E1ZXOvJrII75bPu0l0k843G/+iAbhEqzyKr0w/eCCj7g==", + "dev": true, + "requires": { + "debug": "^3.2.5", + "eventsource": "^1.0.7", + "faye-websocket": "~0.11.1", + "inherits": "^2.0.3", + "json3": "^3.3.2", + "url-parse": "^1.4.3" + }, + "dependencies": { + "debug": { + "version": "3.2.6", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", + "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "faye-websocket": { + "version": "0.11.3", + "resolved": "https://registry.npmjs.org/faye-websocket/-/faye-websocket-0.11.3.tgz", + "integrity": "sha512-D2y4bovYpzziGgbHYtGCMjlJM36vAl/y+xUyn1C+FVx8szd1E+86KwVw6XvYSzOP8iMpm1X0I4xJD+QtUb36OA==", + "dev": true, + "requires": { + "websocket-driver": ">=0.5.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "source-list-map": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", + "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.3", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.3.tgz", + "integrity": "sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true + }, + "spdy": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/spdy/-/spdy-4.0.2.tgz", + "integrity": "sha512-r46gZQZQV+Kl9oItvl1JZZqJKGr+oEkB08A6BzkiR7593/7IbtuncXHd2YoYeTsG4157ZssMu9KYvUHLcjcDoA==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "handle-thing": "^2.0.0", + "http-deceiver": "^1.2.7", + "select-hose": "^2.0.0", + "spdy-transport": "^3.0.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "spdy-transport": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdy-transport/-/spdy-transport-3.0.0.tgz", + "integrity": "sha512-hsLVFE5SjA6TCisWeJXFKniGGOpBgMLmerfO2aCyCU5s7nJ/rpAepqmFifv/GCbSbueEeAJJnmSQ2rKC/g8Fcw==", + "dev": true, + "requires": { + "debug": "^4.1.0", + "detect-node": "^2.0.4", + "hpack.js": "^2.1.6", + "obuf": "^1.1.2", + "readable-stream": "^3.0.6", + "wbuf": "^1.7.3" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "readable-stream": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz", + "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==", + "dev": true, + "requires": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + } + } + } + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "ssri": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-7.1.0.tgz", + "integrity": "sha512-77/WrDZUWocK0mvA5NTRQyveUf+wsrIc6vyrxpS8tVvYBcX215QbafrJR3KtkpskIzoFLqqNuuYQvxaMjXJ/0g==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1", + "minipass": "^3.1.1" + } + }, + "stable": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", + "integrity": "sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==", + "dev": true + }, + "stackframe": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/stackframe/-/stackframe-1.2.0.tgz", + "integrity": "sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "statuses": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.5.0.tgz", + "integrity": "sha1-Fhx9rBd2Wf2YEfQ3cfqZOBR4Yow=", + "dev": true + }, + "stream-browserify": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", + "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", + "dev": true, + "requires": { + "inherits": "~2.0.1", + "readable-stream": "^2.0.2" + } + }, + "stream-each": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", + "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", + "dev": true, + "requires": { + "end-of-stream": "^1.1.0", + "stream-shift": "^1.0.0" + } + }, + "stream-http": { + "version": "2.8.3", + "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", + "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", + "dev": true, + "requires": { + "builtin-status-codes": "^3.0.0", + "inherits": "^2.0.1", + "readable-stream": "^2.3.6", + "to-arraybuffer": "^1.0.0", + "xtend": "^4.0.0" + } + }, + "stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + } + } + }, + "string.prototype.trimend": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz", + "integrity": "sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string.prototype.trimstart": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz", + "integrity": "sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.5" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", + "dev": true + }, + "style-loader": { + "version": "0.23.1", + "resolved": "https://registry.npmjs.org/style-loader/-/style-loader-0.23.1.tgz", + "integrity": "sha512-XK+uv9kWwhZMZ1y7mysB+zoihsEj4wneFWAS5qoiLwzW0WzSqMrrsIy+a3zkQJq0ipFtBpX5W3MqyRIBF/WFGg==", + "dev": true, + "requires": { + "loader-utils": "^1.1.0", + "schema-utils": "^1.0.0" + }, + "dependencies": { + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + } + } + }, + "stylehacks": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/stylehacks/-/stylehacks-4.0.3.tgz", + "integrity": "sha512-7GlLk9JwlElY4Y6a/rmbH2MhVlTyVmiJd1PfTCqFaIBEGMYNsrO/v3SeGTdhBThLg4Z+NbOk/qFMwCa+J+3p/g==", + "dev": true, + "requires": { + "browserslist": "^4.0.0", + "postcss": "^7.0.0", + "postcss-selector-parser": "^3.0.0" + }, + "dependencies": { + "postcss-selector-parser": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/postcss-selector-parser/-/postcss-selector-parser-3.1.2.tgz", + "integrity": "sha512-h7fJ/5uWuRVyOtkO45pnt1Ih40CEleeyCHzipqAZO2e5H20g25Y48uYnFUiShvY4rZWNJ/Bib/KVPmanaCtOhA==", + "dev": true, + "requires": { + "dot-prop": "^5.2.0", + "indexes-of": "^1.0.1", + "uniq": "^1.0.1" + } + } + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "svgo": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz", + "integrity": "sha512-yhy/sQYxR5BkC98CY7o31VGsg014AKLEPxdfhora76l36hD9Rdy5NZA/Ocn6yayNPgSamYdtX2rFJdcv07AYVw==", + "dev": true, + "requires": { + "chalk": "^2.4.1", + "coa": "^2.0.2", + "css-select": "^2.0.0", + "css-select-base-adapter": "^0.1.1", + "css-tree": "1.0.0-alpha.37", + "csso": "^4.0.2", + "js-yaml": "^3.13.1", + "mkdirp": "~0.5.1", + "object.values": "^1.1.0", + "sax": "~1.2.4", + "stable": "^0.1.8", + "unquote": "~1.1.1", + "util.promisify": "~1.0.0" + } + }, + "tapable": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", + "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", + "dev": true + }, + "terser": { + "version": "3.17.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-3.17.0.tgz", + "integrity": "sha512-/FQzzPJmCpjAH9Xvk2paiWrFq+5M6aVOf+2KRbwhByISDX/EujxsK+BAvrhb6H+2rtrLCHK9N01wO014vrIwVQ==", + "dev": true, + "requires": { + "commander": "^2.19.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.10" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "terser-webpack-plugin": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-2.3.7.tgz", + "integrity": "sha512-xzYyaHUNhzgaAdBsXxk2Yvo/x1NJdslUaussK3fdpBbvttm1iIwU+c26dj9UxJcwk2c5UWt5F55MUTIA8BE7Dg==", + "dev": true, + "requires": { + "cacache": "^13.0.1", + "find-cache-dir": "^3.3.1", + "jest-worker": "^25.4.0", + "p-limit": "^2.3.0", + "schema-utils": "^2.6.6", + "serialize-javascript": "^3.1.0", + "source-map": "^0.6.1", + "terser": "^4.6.12", + "webpack-sources": "^1.4.3" + }, + "dependencies": { + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "terser": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz", + "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + } + } + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "through2": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", + "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", + "dev": true, + "requires": { + "readable-stream": "~2.3.6", + "xtend": "~4.0.1" + } + }, + "thunky": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", + "integrity": "sha512-eHY7nBftgThBqOyHGVN+l8gF0BucP09fMo0oO/Lb0w1OF80dJv+lDVpXG60WMQvkcxAkNybKsrEIE3ZtKGmPrA==", + "dev": true + }, + "timers-browserify": { + "version": "2.0.11", + "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", + "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", + "dev": true, + "requires": { + "setimmediate": "^1.0.4" + } + }, + "timsort": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/timsort/-/timsort-0.3.0.tgz", + "integrity": "sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=", + "dev": true + }, + "to-arraybuffer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", + "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", + "dev": true + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "toidentifier": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.0.tgz", + "integrity": "sha512-yaOH/Pk/VEhBWWTlhI+qXxDFXlejDGcQipMlyxda9nthulaxLZUNcUqFxokp0vcYnvteJln5FNQDRrxj3YcbVw==", + "dev": true + }, + "tryer": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/tryer/-/tryer-1.0.1.tgz", + "integrity": "sha512-c3zayb8/kWWpycWYg87P71E1S1ZL6b6IJxfb5fvsUgsf0S2MVGaDhDXXjDMpdCpfWXqptc+4mXwmiy1ypXqRAA==", + "dev": true + }, + "tslib": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.13.0.tgz", + "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==", + "dev": true + }, + "tty-browserify": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", + "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", + "dev": true + }, + "type": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/type/-/type-1.2.0.tgz", + "integrity": "sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==", + "dev": true + }, + "type-is": { + "version": "1.6.18", + "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz", + "integrity": "sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==", + "dev": true, + "requires": { + "media-typer": "0.3.0", + "mime-types": "~2.1.24" + } + }, + "typedarray": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", + "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", + "dev": true + }, + "uglify-js": { + "version": "3.4.10", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.4.10.tgz", + "integrity": "sha512-Y2VsbPVs0FIshJztycsO2SfPk7/KAF/T72qzv9u5EpQ4kB2hQoHlhNQTsNyy6ul7lQtqJN/AoWeS23OzEiEFxw==", + "dev": true, + "requires": { + "commander": "~2.19.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "commander": { + "version": "2.19.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.19.0.tgz", + "integrity": "sha512-6tvAOO+D6OENvRAh524Dh9jcfKTYDQAqvqezbCW82xj5X0pSrcpxtvRKHLG0yBY6SD7PSDrJaj+0AiOcKVd1Xg==", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz", + "integrity": "sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.1.0.tgz", + "integrity": "sha512-PqSoPh/pWetQ2phoj5RLiaqIk4kCNwoV3CI+LfGmWLKI3rE3kl1h59XpX2BjgDrmbxD9ARtQobPGU1SguCYuQg==", + "dev": true + }, + "union-value": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", + "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", + "dev": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^2.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true + } + } + }, + "uniq": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/uniq/-/uniq-1.0.1.tgz", + "integrity": "sha1-sxxa6CVIRKOoKBVBzisEuGWnNP8=", + "dev": true + }, + "uniqs": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/uniqs/-/uniqs-2.0.0.tgz", + "integrity": "sha1-/+3ks2slKQaW5uFl1KWe25mOawI=", + "dev": true + }, + "unique-filename": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", + "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", + "dev": true, + "requires": { + "unique-slug": "^2.0.0" + } + }, + "unique-slug": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", + "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4" + } + }, + "universalify": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/universalify/-/universalify-0.1.2.tgz", + "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==", + "dev": true + }, + "unpipe": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", + "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw=", + "dev": true + }, + "unquote": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/unquote/-/unquote-1.1.1.tgz", + "integrity": "sha1-j97XMk7G6IoP+LkF58CYzcCG1UQ=", + "dev": true + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true + } + } + }, + "upath": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.2.0.tgz", + "integrity": "sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==", + "dev": true + }, + "upper-case": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", + "integrity": "sha1-9rRQHC7EzdJrp4vnIilh3ndiFZg=", + "dev": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true + }, + "url": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", + "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", + "dev": true, + "requires": { + "punycode": "1.3.2", + "querystring": "0.2.0" + }, + "dependencies": { + "punycode": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", + "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", + "dev": true + } + } + }, + "url-parse": { + "version": "1.4.7", + "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz", + "integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==", + "dev": true, + "requires": { + "querystringify": "^2.1.1", + "requires-port": "^1.0.0" + } + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true + }, + "util": { + "version": "0.11.1", + "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", + "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", + "dev": true, + "requires": { + "inherits": "2.0.3" + }, + "dependencies": { + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + } + } + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true + }, + "util.promisify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/util.promisify/-/util.promisify-1.0.1.tgz", + "integrity": "sha512-g9JpC/3He3bm38zsLupWryXHoEcS22YHthuPQSJdMy6KNrzIRzWqcsHzD/WUnqe45whVou4VIsPew37DoXWNrA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.17.2", + "has-symbols": "^1.0.1", + "object.getownpropertydescriptors": "^2.1.0" + } + }, + "utils-merge": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz", + "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "v8-compile-cache": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", + "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", + "dev": true + }, + "vary": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", + "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", + "dev": true + }, + "vendors": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/vendors/-/vendors-1.0.4.tgz", + "integrity": "sha512-/juG65kTL4Cy2su4P8HjtkTxk6VmJDiOPBufWniqQ6wknac6jNiXS9vU+hO3wgusiyqWlzTbVHi0dyJqRONg3w==", + "dev": true + }, + "vm-browserify": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.2.tgz", + "integrity": "sha512-2ham8XPWTONajOR0ohOKOHXkm3+gaBmGut3SRuu75xLd/RRaY6vqgh8NBYYk7+RW3u5AtzPQZG8F10LHkl0lAQ==", + "dev": true + }, + "vue": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/vue/-/vue-2.6.11.tgz", + "integrity": "sha512-VfPwgcGABbGAue9+sfrD4PuwFar7gPb1yl1UK1MwXoQPAw0BKSqWfoYCT/ThFrdEVWoI51dBuyCoiNU9bZDZxQ==", + "dev": true + }, + "vue-chartjs": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-3.5.0.tgz", + "integrity": "sha512-yWNhG3B6g6lvYqNInP0WaDWNZG/SNb6XnltkjR0wYC5pmLm6jvdiotj8er7Mui8qkJGfLZe6ULjrZdHWjegAUg==" + }, + "vue-hot-reload-api": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/vue-hot-reload-api/-/vue-hot-reload-api-2.3.4.tgz", + "integrity": "sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog==", + "dev": true + }, + "vue-i18n": { + "version": "8.18.2", + "resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-8.18.2.tgz", + "integrity": "sha512-0X5nBTCZAVjlwcrPaYJwNs3iipBBTv0AUHwQUOa8yP3XbQGWKbRHqBb3OhCYtum/IHDD21d/df5Xd2VgyxbxfA==", + "dev": true + }, + "vue-loader": { + "version": "15.9.2", + "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-15.9.2.tgz", + "integrity": "sha512-oXBubaY//CYEISBlHX+c2YPJbmOH68xXPXjFv4MAgPqQvUsnjrBAjCJi8HXZ/r/yfn0tPL5VZj1Zcp8mJPI8VA==", + "dev": true, + "requires": { + "@vue/component-compiler-utils": "^3.1.0", + "hash-sum": "^1.0.2", + "loader-utils": "^1.1.0", + "vue-hot-reload-api": "^2.3.0", + "vue-style-loader": "^4.1.0" + } + }, + "vue-style-loader": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/vue-style-loader/-/vue-style-loader-4.1.2.tgz", + "integrity": "sha512-0ip8ge6Gzz/Bk0iHovU9XAUQaFt/G2B61bnWa2tCcqqdgfHs1lF9xXorFbE55Gmy92okFT+8bfmySuUOu13vxQ==", + "dev": true, + "requires": { + "hash-sum": "^1.0.2", + "loader-utils": "^1.0.2" + } + }, + "vue-template-compiler": { + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/vue-template-compiler/-/vue-template-compiler-2.6.11.tgz", + "integrity": "sha512-KIq15bvQDrcCjpGjrAhx4mUlyyHfdmTaoNfeoATHLAiWB+MU3cx4lOzMwrnUh9cCxy0Lt1T11hAFY6TQgroUAA==", + "dev": true, + "requires": { + "de-indent": "^1.0.2", + "he": "^1.1.0" + } + }, + "vue-template-es2015-compiler": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/vue-template-es2015-compiler/-/vue-template-es2015-compiler-1.9.1.tgz", + "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==", + "dev": true + }, + "watchpack": { + "version": "1.7.2", + "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.7.2.tgz", + "integrity": "sha512-ymVbbQP40MFTp+cNMvpyBpBtygHnPzPkHqoIwRRj/0B8KhqQwV8LaKjtbaxF2lK4vl8zN9wCxS46IFCU5K4W0g==", + "dev": true, + "requires": { + "chokidar": "^3.4.0", + "graceful-fs": "^4.1.2", + "neo-async": "^2.5.0", + "watchpack-chokidar2": "^2.0.0" + }, + "dependencies": { + "anymatch": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.1.tgz", + "integrity": "sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg==", + "dev": true, + "optional": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "binary-extensions": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.0.0.tgz", + "integrity": "sha512-Phlt0plgpIIBOGTT/ehfFnbNlfsDEiqmzE2KRXoX1bLIlir4X/MR+zSyBEkL05ffWgnRSf/DXv+WrUAVr93/ow==", + "dev": true, + "optional": true + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "optional": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "chokidar": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.4.0.tgz", + "integrity": "sha512-aXAaho2VJtisB/1fg1+3nlLJqGOuewTzQpd/Tz0yTg2R0e4IGtshYvtjowyEumcBv2z+y4+kc75Mz7j5xJskcQ==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.1.2", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.4.0" + } + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "optional": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "fsevents": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.1.3.tgz", + "integrity": "sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ==", + "dev": true, + "optional": true + }, + "glob-parent": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.1.tgz", + "integrity": "sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ==", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true, + "optional": true + }, + "readdirp": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.4.0.tgz", + "integrity": "sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ==", + "dev": true, + "optional": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "optional": true, + "requires": { + "is-number": "^7.0.0" + } + } + } + }, + "watchpack-chokidar2": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/watchpack-chokidar2/-/watchpack-chokidar2-2.0.0.tgz", + "integrity": "sha512-9TyfOyN/zLUbA288wZ8IsMZ+6cbzvsNyEzSBp6e/zkifi6xxbl8SmQ/CxQq32k8NNqrdVEVUVSEf56L4rQ/ZxA==", + "dev": true, + "optional": true, + "requires": { + "chokidar": "^2.1.8" + } + }, + "wbuf": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/wbuf/-/wbuf-1.7.3.tgz", + "integrity": "sha512-O84QOnr0icsbFGLS0O3bI5FswxzRr8/gHwWkDlQFskhSPryQXvrTMxjxGP4+iWYoauLoBvfDpkrOauZ+0iZpDA==", + "dev": true, + "requires": { + "minimalistic-assert": "^1.0.0" + } + }, + "webpack": { + "version": "4.43.0", + "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.43.0.tgz", + "integrity": "sha512-GW1LjnPipFW2Y78OOab8NJlCflB7EFskMih2AHdvjbpKMeDJqEgSx24cXXXiPS65+WSwVyxtDsJH6jGX2czy+g==", + "dev": true, + "requires": { + "@webassemblyjs/ast": "1.9.0", + "@webassemblyjs/helper-module-context": "1.9.0", + "@webassemblyjs/wasm-edit": "1.9.0", + "@webassemblyjs/wasm-parser": "1.9.0", + "acorn": "^6.4.1", + "ajv": "^6.10.2", + "ajv-keywords": "^3.4.1", + "chrome-trace-event": "^1.0.2", + "enhanced-resolve": "^4.1.0", + "eslint-scope": "^4.0.3", + "json-parse-better-errors": "^1.0.2", + "loader-runner": "^2.4.0", + "loader-utils": "^1.2.3", + "memory-fs": "^0.4.1", + "micromatch": "^3.1.10", + "mkdirp": "^0.5.3", + "neo-async": "^2.6.1", + "node-libs-browser": "^2.2.1", + "schema-utils": "^1.0.0", + "tapable": "^1.1.3", + "terser-webpack-plugin": "^1.4.3", + "watchpack": "^1.6.1", + "webpack-sources": "^1.4.1" + }, + "dependencies": { + "cacache": { + "version": "12.0.4", + "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.4.tgz", + "integrity": "sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==", + "dev": true, + "requires": { + "bluebird": "^3.5.5", + "chownr": "^1.1.1", + "figgy-pudding": "^3.5.1", + "glob": "^7.1.4", + "graceful-fs": "^4.1.15", + "infer-owner": "^1.0.3", + "lru-cache": "^5.1.1", + "mississippi": "^3.0.0", + "mkdirp": "^0.5.1", + "move-concurrently": "^1.0.1", + "promise-inflight": "^1.0.1", + "rimraf": "^2.6.3", + "ssri": "^6.0.1", + "unique-filename": "^1.1.1", + "y18n": "^4.0.0" + } + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "ssri": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", + "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", + "dev": true, + "requires": { + "figgy-pudding": "^3.5.1" + } + }, + "terser": { + "version": "4.7.0", + "resolved": "https://registry.npmjs.org/terser/-/terser-4.7.0.tgz", + "integrity": "sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw==", + "dev": true, + "requires": { + "commander": "^2.20.0", + "source-map": "~0.6.1", + "source-map-support": "~0.5.12" + } + }, + "terser-webpack-plugin": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.4.tgz", + "integrity": "sha512-U4mACBHIegmfoEe5fdongHESNJWqsGU+W0S/9+BmYGVQDw1+c2Ow05TpMhxjPK1sRb7cuYq1BPl1e5YHJMTCqA==", + "dev": true, + "requires": { + "cacache": "^12.0.2", + "find-cache-dir": "^2.1.0", + "is-wsl": "^1.1.0", + "schema-utils": "^1.0.0", + "serialize-javascript": "^3.1.0", + "source-map": "^0.6.1", + "terser": "^4.1.2", + "webpack-sources": "^1.4.0", + "worker-farm": "^1.7.0" + } + } + } + }, + "webpack-bundle-analyzer": { + "version": "3.8.0", + "resolved": "https://registry.npmjs.org/webpack-bundle-analyzer/-/webpack-bundle-analyzer-3.8.0.tgz", + "integrity": "sha512-PODQhAYVEourCcOuU+NiYI7WdR8QyELZGgPvB1y2tjbUpbmcQOt5Q7jEK+ttd5se0KSBKD9SXHCEozS++Wllmw==", + "dev": true, + "requires": { + "acorn": "^7.1.1", + "acorn-walk": "^7.1.1", + "bfj": "^6.1.1", + "chalk": "^2.4.1", + "commander": "^2.18.0", + "ejs": "^2.6.1", + "express": "^4.16.3", + "filesize": "^3.6.1", + "gzip-size": "^5.0.0", + "lodash": "^4.17.15", + "mkdirp": "^0.5.1", + "opener": "^1.5.1", + "ws": "^6.0.0" + }, + "dependencies": { + "acorn": { + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.3.1.tgz", + "integrity": "sha512-tLc0wSnatxAQHVHUapaHdz72pi9KUyHjq5KyHjGg9Y8Ifdc79pTh2XvI6I1/chZbnM7QtNKzh66ooDogPZSleA==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + } + } + }, + "webpack-cli": { + "version": "3.3.11", + "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.11.tgz", + "integrity": "sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g==", + "dev": true, + "requires": { + "chalk": "2.4.2", + "cross-spawn": "6.0.5", + "enhanced-resolve": "4.1.0", + "findup-sync": "3.0.0", + "global-modules": "2.0.0", + "import-local": "2.0.0", + "interpret": "1.2.0", + "loader-utils": "1.2.3", + "supports-color": "6.1.0", + "v8-compile-cache": "2.0.3", + "yargs": "13.2.4" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "emojis-list": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", + "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", + "dev": true + }, + "enhanced-resolve": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", + "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "memory-fs": "^0.4.0", + "tapable": "^1.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "json5": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", + "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + } + }, + "loader-utils": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", + "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", + "dev": true, + "requires": { + "big.js": "^5.2.2", + "emojis-list": "^2.0.0", + "json5": "^1.0.1" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "yargs": { + "version": "13.2.4", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", + "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "os-locale": "^3.1.0", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.0" + } + } + } + }, + "webpack-dev-middleware": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz", + "integrity": "sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw==", + "dev": true, + "requires": { + "memory-fs": "^0.4.1", + "mime": "^2.4.4", + "mkdirp": "^0.5.1", + "range-parser": "^1.2.1", + "webpack-log": "^2.0.0" + }, + "dependencies": { + "mime": { + "version": "2.4.6", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.4.6.tgz", + "integrity": "sha512-RZKhC3EmpBchfTGBVb8fb+RL2cWyw/32lshnsETttkBAyAUXSGHxbEJWWRXc751DrIxG1q04b8QwMbAwkRPpUA==", + "dev": true + } + } + }, + "webpack-dev-server": { + "version": "3.11.0", + "resolved": "https://registry.npmjs.org/webpack-dev-server/-/webpack-dev-server-3.11.0.tgz", + "integrity": "sha512-PUxZ+oSTxogFQgkTtFndEtJIPNmml7ExwufBZ9L2/Xyyd5PnOL5UreWe5ZT7IU25DSdykL9p1MLQzmLh2ljSeg==", + "dev": true, + "requires": { + "ansi-html": "0.0.7", + "bonjour": "^3.5.0", + "chokidar": "^2.1.8", + "compression": "^1.7.4", + "connect-history-api-fallback": "^1.6.0", + "debug": "^4.1.1", + "del": "^4.1.1", + "express": "^4.17.1", + "html-entities": "^1.3.1", + "http-proxy-middleware": "0.19.1", + "import-local": "^2.0.0", + "internal-ip": "^4.3.0", + "ip": "^1.1.5", + "is-absolute-url": "^3.0.3", + "killable": "^1.0.1", + "loglevel": "^1.6.8", + "opn": "^5.5.0", + "p-retry": "^3.0.1", + "portfinder": "^1.0.26", + "schema-utils": "^1.0.0", + "selfsigned": "^1.10.7", + "semver": "^6.3.0", + "serve-index": "^1.9.1", + "sockjs": "0.3.20", + "sockjs-client": "1.4.0", + "spdy": "^4.0.2", + "strip-ansi": "^3.0.1", + "supports-color": "^6.1.0", + "url": "^0.11.0", + "webpack-dev-middleware": "^3.7.2", + "webpack-log": "^2.0.0", + "ws": "^6.2.1", + "yargs": "^13.3.2" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "is-absolute-url": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-absolute-url/-/is-absolute-url-3.0.3.tgz", + "integrity": "sha512-opmNIX7uFnS96NtPmhWQgQx6/NYFgsUXYMllcfzwWKUMwfo8kku1TvE6hkNcH+Q1ts5cMVrsY7j0bxXQDciu9Q==", + "dev": true + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "schema-utils": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", + "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", + "dev": true, + "requires": { + "ajv": "^6.1.0", + "ajv-errors": "^1.0.0", + "ajv-keywords": "^3.1.0" + } + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + }, + "dependencies": { + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "supports-color": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", + "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "yargs": { + "version": "13.3.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.2.tgz", + "integrity": "sha512-AX3Zw5iPruN5ie6xGRIDgqkT+ZhnRlZMLMHAs8tg7nRruy2Nb+i5o9bwghAogtM08q1dpr2LVoS8KSTMYpWXUw==", + "dev": true, + "requires": { + "cliui": "^5.0.0", + "find-up": "^3.0.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^3.0.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^13.1.2" + } + } + } + }, + "webpack-log": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/webpack-log/-/webpack-log-2.0.0.tgz", + "integrity": "sha512-cX8G2vR/85UYG59FgkoMamwHUIkSSlV3bBMRsbxVXVUk2j6NleCKjQ/WE9eYg9WY4w25O9w8wKP4rzNZFmUcUg==", + "dev": true, + "requires": { + "ansi-colors": "^3.0.0", + "uuid": "^3.3.2" + } + }, + "webpack-merge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-4.2.2.tgz", + "integrity": "sha512-TUE1UGoTX2Cd42j3krGYqObZbOD+xF7u28WB7tfUordytSjbWTIjK/8V0amkBfTYN4/pB/GIDlJZZ657BGG19g==", + "dev": true, + "requires": { + "lodash": "^4.17.15" + } + }, + "webpack-notifier": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/webpack-notifier/-/webpack-notifier-1.8.0.tgz", + "integrity": "sha512-I6t76NoPe5DZCCm5geELmDV2wlJ89LbU425uN6T2FG8Ywrrt1ZcUMz6g8yWGNg4pttqTPFQJYUPjWAlzUEQ+cQ==", + "dev": true, + "requires": { + "node-notifier": "^5.1.2", + "object-assign": "^4.1.0", + "strip-ansi": "^3.0.1" + } + }, + "webpack-sources": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", + "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", + "dev": true, + "requires": { + "source-list-map": "^2.0.0", + "source-map": "~0.6.1" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, + "websocket-driver": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/websocket-driver/-/websocket-driver-0.6.5.tgz", + "integrity": "sha1-XLJVbOuF9Dc8bYI4qmkchFThOjY=", + "dev": true, + "requires": { + "websocket-extensions": ">=0.1.1" + } + }, + "websocket-extensions": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/websocket-extensions/-/websocket-extensions-0.1.4.tgz", + "integrity": "sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "which-module": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", + "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", + "dev": true + }, + "worker-farm": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", + "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", + "dev": true, + "requires": { + "errno": "~0.1.7" + } + }, + "wrap-ansi": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", + "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "string-width": "^3.0.0", + "strip-ansi": "^5.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "ws": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-6.2.1.tgz", + "integrity": "sha512-GIyAXC2cB7LjvpgMt9EKS2ldqr0MTrORaleiOno6TweZ6r3TKtoFQWay/2PceJ3RuBasOHzXNn5Lrw1X0bEjqA==", + "dev": true, + "requires": { + "async-limiter": "~1.0.0" + } + }, + "xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "dev": true + }, + "y18n": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", + "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", + "dev": true + }, + "yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==", + "dev": true + }, + "yargs": { + "version": "12.0.5", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", + "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", + "dev": true, + "requires": { + "cliui": "^4.0.0", + "decamelize": "^1.2.0", + "find-up": "^3.0.0", + "get-caller-file": "^1.0.1", + "os-locale": "^3.0.0", + "require-directory": "^2.1.1", + "require-main-filename": "^1.0.1", + "set-blocking": "^2.0.0", + "string-width": "^2.0.0", + "which-module": "^2.0.0", + "y18n": "^3.2.1 || ^4.0.0", + "yargs-parser": "^11.1.1" + }, + "dependencies": { + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "cliui": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", + "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", + "dev": true, + "requires": { + "string-width": "^2.1.1", + "strip-ansi": "^4.0.0", + "wrap-ansi": "^2.0.0" + } + }, + "find-up": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", + "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", + "dev": true, + "requires": { + "locate-path": "^3.0.0" + } + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", + "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", + "dev": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "locate-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", + "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", + "dev": true, + "requires": { + "p-locate": "^3.0.0", + "path-exists": "^3.0.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", + "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", + "dev": true, + "requires": { + "p-limit": "^2.0.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "require-main-filename": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", + "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", + "dev": true + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "wrap-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", + "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", + "dev": true, + "requires": { + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1" + }, + "dependencies": { + "ansi-regex": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", + "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=", + "dev": true + }, + "string-width": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", + "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", + "dev": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", + "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", + "dev": true, + "requires": { + "ansi-regex": "^2.0.0" + } + } + } + }, + "yargs-parser": { + "version": "11.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", + "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, + "yargs-parser": { + "version": "13.1.2", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz", + "integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } +} diff --git a/frontend/package.json b/frontend/package.json new file mode 100755 index 0000000000..74dc8b2963 --- /dev/null +++ b/frontend/package.json @@ -0,0 +1,37 @@ +{ + "private": true, + "scripts": { + "dev": "npm run development", + "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js", + "watch": "npm run development -- --watch", + "watch-poll": "npm run watch -- --watch-poll", + "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --disable-host-check --config=node_modules/laravel-mix/setup/webpack.config.js", + "prod": "npm run production", + "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js" + }, + "devDependencies": { + "axios": "^0.19", + "cross-env": "^7.0", + "laravel-mix": "^5.0.1", + "laravel-mix-bundle-analyzer": "^1.0.5", + "lodash": "^4.17.13", + "resolve-url-loader": "^3.1.0", + "sass": "^1.15.2", + "sass-loader": "^8.0.0", + "vue": "^2.6", + "vue-i18n": "^8.15", + "vue-template-compiler": "^2.6.11" + }, + "dependencies": { + "@fortawesome/fontawesome-free": "^5.13.0", + "@popperjs/core": "^2.4.2", + "bootstrap": "^4.5.0", + "chart.js": "^2.9.3", + "icheck-bootstrap": "^3.0.1", + "jquery": "^3.5.1", + "jquery-ui": "^1.12.1", + "overlayscrollbars": "^1.12.0", + "popper.js": "^1.16.1", + "vue-chartjs": "^3.5.0" + } +} diff --git a/frontend/public/css/app.css b/frontend/public/css/app.css new file mode 100644 index 0000000000..7cc1242e92 --- /dev/null +++ b/frontend/public/css/app.css @@ -0,0 +1,32 @@ +/*! + * Font Awesome Free 5.13.0 by @fontawesome - https://fontawesome.com + * License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) + */.fa,.fab,.fad,.fal,.far,.fas{-moz-osx-font-smoothing:grayscale;-webkit-font-smoothing:antialiased;display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;line-height:1}.fa-lg{font-size:1.33333em;line-height:.75em;vertical-align:-.0667em}.fa-xs{font-size:.75em}.fa-sm{font-size:.875em}.fa-1x{font-size:1em}.fa-2x{font-size:2em}.fa-3x{font-size:3em}.fa-4x{font-size:4em}.fa-5x{font-size:5em}.fa-6x{font-size:6em}.fa-7x{font-size:7em}.fa-8x{font-size:8em}.fa-9x{font-size:9em}.fa-10x{font-size:10em}.fa-fw{text-align:center;width:1.25em}.fa-ul{list-style-type:none;margin-left:2.5em;padding-left:0}.fa-ul>li{position:relative}.fa-li{left:-2em;position:absolute;text-align:center;width:2em;line-height:inherit}.fa-border{border:.08em solid #eee;border-radius:.1em;padding:.2em .25em .15em}.fa-pull-left{float:left}.fa-pull-right{float:right}.fa.fa-pull-left,.fab.fa-pull-left,.fal.fa-pull-left,.far.fa-pull-left,.fas.fa-pull-left{margin-right:.3em}.fa.fa-pull-right,.fab.fa-pull-right,.fal.fa-pull-right,.far.fa-pull-right,.fas.fa-pull-right{margin-left:.3em}.fa-spin{-webkit-animation:fa-spin 2s linear infinite;animation:fa-spin 2s linear infinite}.fa-pulse{-webkit-animation:fa-spin 1s steps(8) infinite;animation:fa-spin 1s steps(8) infinite}@-webkit-keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes fa-spin{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.fa-rotate-90{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=1)";transform:rotate(90deg)}.fa-rotate-180{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2)";transform:rotate(180deg)}.fa-rotate-270{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=3)";transform:rotate(270deg)}.fa-flip-horizontal{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)";transform:scaleX(-1)}.fa-flip-vertical{transform:scaleY(-1)}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical,.fa-flip-vertical{-ms-filter:"progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"}.fa-flip-both,.fa-flip-horizontal.fa-flip-vertical{transform:scale(-1)}:root .fa-flip-both,:root .fa-flip-horizontal,:root .fa-flip-vertical,:root .fa-rotate-90,:root .fa-rotate-180,:root .fa-rotate-270{-webkit-filter:none;filter:none}.fa-stack{display:inline-block;height:2em;line-height:2em;position:relative;vertical-align:middle;width:2.5em}.fa-stack-1x,.fa-stack-2x{left:0;position:absolute;text-align:center;width:100%}.fa-stack-1x{line-height:inherit}.fa-stack-2x{font-size:2em}.fa-inverse{color:#fff}.fa-500px:before{content:"\F26E"}.fa-accessible-icon:before{content:"\F368"}.fa-accusoft:before{content:"\F369"}.fa-acquisitions-incorporated:before{content:"\F6AF"}.fa-ad:before{content:"\F641"}.fa-address-book:before{content:"\F2B9"}.fa-address-card:before{content:"\F2BB"}.fa-adjust:before{content:"\F042"}.fa-adn:before{content:"\F170"}.fa-adobe:before{content:"\F778"}.fa-adversal:before{content:"\F36A"}.fa-affiliatetheme:before{content:"\F36B"}.fa-air-freshener:before{content:"\F5D0"}.fa-airbnb:before{content:"\F834"}.fa-algolia:before{content:"\F36C"}.fa-align-center:before{content:"\F037"}.fa-align-justify:before{content:"\F039"}.fa-align-left:before{content:"\F036"}.fa-align-right:before{content:"\F038"}.fa-alipay:before{content:"\F642"}.fa-allergies:before{content:"\F461"}.fa-amazon:before{content:"\F270"}.fa-amazon-pay:before{content:"\F42C"}.fa-ambulance:before{content:"\F0F9"}.fa-american-sign-language-interpreting:before{content:"\F2A3"}.fa-amilia:before{content:"\F36D"}.fa-anchor:before{content:"\F13D"}.fa-android:before{content:"\F17B"}.fa-angellist:before{content:"\F209"}.fa-angle-double-down:before{content:"\F103"}.fa-angle-double-left:before{content:"\F100"}.fa-angle-double-right:before{content:"\F101"}.fa-angle-double-up:before{content:"\F102"}.fa-angle-down:before{content:"\F107"}.fa-angle-left:before{content:"\F104"}.fa-angle-right:before{content:"\F105"}.fa-angle-up:before{content:"\F106"}.fa-angry:before{content:"\F556"}.fa-angrycreative:before{content:"\F36E"}.fa-angular:before{content:"\F420"}.fa-ankh:before{content:"\F644"}.fa-app-store:before{content:"\F36F"}.fa-app-store-ios:before{content:"\F370"}.fa-apper:before{content:"\F371"}.fa-apple:before{content:"\F179"}.fa-apple-alt:before{content:"\F5D1"}.fa-apple-pay:before{content:"\F415"}.fa-archive:before{content:"\F187"}.fa-archway:before{content:"\F557"}.fa-arrow-alt-circle-down:before{content:"\F358"}.fa-arrow-alt-circle-left:before{content:"\F359"}.fa-arrow-alt-circle-right:before{content:"\F35A"}.fa-arrow-alt-circle-up:before{content:"\F35B"}.fa-arrow-circle-down:before{content:"\F0AB"}.fa-arrow-circle-left:before{content:"\F0A8"}.fa-arrow-circle-right:before{content:"\F0A9"}.fa-arrow-circle-up:before{content:"\F0AA"}.fa-arrow-down:before{content:"\F063"}.fa-arrow-left:before{content:"\F060"}.fa-arrow-right:before{content:"\F061"}.fa-arrow-up:before{content:"\F062"}.fa-arrows-alt:before{content:"\F0B2"}.fa-arrows-alt-h:before{content:"\F337"}.fa-arrows-alt-v:before{content:"\F338"}.fa-artstation:before{content:"\F77A"}.fa-assistive-listening-systems:before{content:"\F2A2"}.fa-asterisk:before{content:"\F069"}.fa-asymmetrik:before{content:"\F372"}.fa-at:before{content:"\F1FA"}.fa-atlas:before{content:"\F558"}.fa-atlassian:before{content:"\F77B"}.fa-atom:before{content:"\F5D2"}.fa-audible:before{content:"\F373"}.fa-audio-description:before{content:"\F29E"}.fa-autoprefixer:before{content:"\F41C"}.fa-avianex:before{content:"\F374"}.fa-aviato:before{content:"\F421"}.fa-award:before{content:"\F559"}.fa-aws:before{content:"\F375"}.fa-baby:before{content:"\F77C"}.fa-baby-carriage:before{content:"\F77D"}.fa-backspace:before{content:"\F55A"}.fa-backward:before{content:"\F04A"}.fa-bacon:before{content:"\F7E5"}.fa-bahai:before{content:"\F666"}.fa-balance-scale:before{content:"\F24E"}.fa-balance-scale-left:before{content:"\F515"}.fa-balance-scale-right:before{content:"\F516"}.fa-ban:before{content:"\F05E"}.fa-band-aid:before{content:"\F462"}.fa-bandcamp:before{content:"\F2D5"}.fa-barcode:before{content:"\F02A"}.fa-bars:before{content:"\F0C9"}.fa-baseball-ball:before{content:"\F433"}.fa-basketball-ball:before{content:"\F434"}.fa-bath:before{content:"\F2CD"}.fa-battery-empty:before{content:"\F244"}.fa-battery-full:before{content:"\F240"}.fa-battery-half:before{content:"\F242"}.fa-battery-quarter:before{content:"\F243"}.fa-battery-three-quarters:before{content:"\F241"}.fa-battle-net:before{content:"\F835"}.fa-bed:before{content:"\F236"}.fa-beer:before{content:"\F0FC"}.fa-behance:before{content:"\F1B4"}.fa-behance-square:before{content:"\F1B5"}.fa-bell:before{content:"\F0F3"}.fa-bell-slash:before{content:"\F1F6"}.fa-bezier-curve:before{content:"\F55B"}.fa-bible:before{content:"\F647"}.fa-bicycle:before{content:"\F206"}.fa-biking:before{content:"\F84A"}.fa-bimobject:before{content:"\F378"}.fa-binoculars:before{content:"\F1E5"}.fa-biohazard:before{content:"\F780"}.fa-birthday-cake:before{content:"\F1FD"}.fa-bitbucket:before{content:"\F171"}.fa-bitcoin:before{content:"\F379"}.fa-bity:before{content:"\F37A"}.fa-black-tie:before{content:"\F27E"}.fa-blackberry:before{content:"\F37B"}.fa-blender:before{content:"\F517"}.fa-blender-phone:before{content:"\F6B6"}.fa-blind:before{content:"\F29D"}.fa-blog:before{content:"\F781"}.fa-blogger:before{content:"\F37C"}.fa-blogger-b:before{content:"\F37D"}.fa-bluetooth:before{content:"\F293"}.fa-bluetooth-b:before{content:"\F294"}.fa-bold:before{content:"\F032"}.fa-bolt:before{content:"\F0E7"}.fa-bomb:before{content:"\F1E2"}.fa-bone:before{content:"\F5D7"}.fa-bong:before{content:"\F55C"}.fa-book:before{content:"\F02D"}.fa-book-dead:before{content:"\F6B7"}.fa-book-medical:before{content:"\F7E6"}.fa-book-open:before{content:"\F518"}.fa-book-reader:before{content:"\F5DA"}.fa-bookmark:before{content:"\F02E"}.fa-bootstrap:before{content:"\F836"}.fa-border-all:before{content:"\F84C"}.fa-border-none:before{content:"\F850"}.fa-border-style:before{content:"\F853"}.fa-bowling-ball:before{content:"\F436"}.fa-box:before{content:"\F466"}.fa-box-open:before{content:"\F49E"}.fa-box-tissue:before{content:"\F95B"}.fa-boxes:before{content:"\F468"}.fa-braille:before{content:"\F2A1"}.fa-brain:before{content:"\F5DC"}.fa-bread-slice:before{content:"\F7EC"}.fa-briefcase:before{content:"\F0B1"}.fa-briefcase-medical:before{content:"\F469"}.fa-broadcast-tower:before{content:"\F519"}.fa-broom:before{content:"\F51A"}.fa-brush:before{content:"\F55D"}.fa-btc:before{content:"\F15A"}.fa-buffer:before{content:"\F837"}.fa-bug:before{content:"\F188"}.fa-building:before{content:"\F1AD"}.fa-bullhorn:before{content:"\F0A1"}.fa-bullseye:before{content:"\F140"}.fa-burn:before{content:"\F46A"}.fa-buromobelexperte:before{content:"\F37F"}.fa-bus:before{content:"\F207"}.fa-bus-alt:before{content:"\F55E"}.fa-business-time:before{content:"\F64A"}.fa-buy-n-large:before{content:"\F8A6"}.fa-buysellads:before{content:"\F20D"}.fa-calculator:before{content:"\F1EC"}.fa-calendar:before{content:"\F133"}.fa-calendar-alt:before{content:"\F073"}.fa-calendar-check:before{content:"\F274"}.fa-calendar-day:before{content:"\F783"}.fa-calendar-minus:before{content:"\F272"}.fa-calendar-plus:before{content:"\F271"}.fa-calendar-times:before{content:"\F273"}.fa-calendar-week:before{content:"\F784"}.fa-camera:before{content:"\F030"}.fa-camera-retro:before{content:"\F083"}.fa-campground:before{content:"\F6BB"}.fa-canadian-maple-leaf:before{content:"\F785"}.fa-candy-cane:before{content:"\F786"}.fa-cannabis:before{content:"\F55F"}.fa-capsules:before{content:"\F46B"}.fa-car:before{content:"\F1B9"}.fa-car-alt:before{content:"\F5DE"}.fa-car-battery:before{content:"\F5DF"}.fa-car-crash:before{content:"\F5E1"}.fa-car-side:before{content:"\F5E4"}.fa-caravan:before{content:"\F8FF"}.fa-caret-down:before{content:"\F0D7"}.fa-caret-left:before{content:"\F0D9"}.fa-caret-right:before{content:"\F0DA"}.fa-caret-square-down:before{content:"\F150"}.fa-caret-square-left:before{content:"\F191"}.fa-caret-square-right:before{content:"\F152"}.fa-caret-square-up:before{content:"\F151"}.fa-caret-up:before{content:"\F0D8"}.fa-carrot:before{content:"\F787"}.fa-cart-arrow-down:before{content:"\F218"}.fa-cart-plus:before{content:"\F217"}.fa-cash-register:before{content:"\F788"}.fa-cat:before{content:"\F6BE"}.fa-cc-amazon-pay:before{content:"\F42D"}.fa-cc-amex:before{content:"\F1F3"}.fa-cc-apple-pay:before{content:"\F416"}.fa-cc-diners-club:before{content:"\F24C"}.fa-cc-discover:before{content:"\F1F2"}.fa-cc-jcb:before{content:"\F24B"}.fa-cc-mastercard:before{content:"\F1F1"}.fa-cc-paypal:before{content:"\F1F4"}.fa-cc-stripe:before{content:"\F1F5"}.fa-cc-visa:before{content:"\F1F0"}.fa-centercode:before{content:"\F380"}.fa-centos:before{content:"\F789"}.fa-certificate:before{content:"\F0A3"}.fa-chair:before{content:"\F6C0"}.fa-chalkboard:before{content:"\F51B"}.fa-chalkboard-teacher:before{content:"\F51C"}.fa-charging-station:before{content:"\F5E7"}.fa-chart-area:before{content:"\F1FE"}.fa-chart-bar:before{content:"\F080"}.fa-chart-line:before{content:"\F201"}.fa-chart-pie:before{content:"\F200"}.fa-check:before{content:"\F00C"}.fa-check-circle:before{content:"\F058"}.fa-check-double:before{content:"\F560"}.fa-check-square:before{content:"\F14A"}.fa-cheese:before{content:"\F7EF"}.fa-chess:before{content:"\F439"}.fa-chess-bishop:before{content:"\F43A"}.fa-chess-board:before{content:"\F43C"}.fa-chess-king:before{content:"\F43F"}.fa-chess-knight:before{content:"\F441"}.fa-chess-pawn:before{content:"\F443"}.fa-chess-queen:before{content:"\F445"}.fa-chess-rook:before{content:"\F447"}.fa-chevron-circle-down:before{content:"\F13A"}.fa-chevron-circle-left:before{content:"\F137"}.fa-chevron-circle-right:before{content:"\F138"}.fa-chevron-circle-up:before{content:"\F139"}.fa-chevron-down:before{content:"\F078"}.fa-chevron-left:before{content:"\F053"}.fa-chevron-right:before{content:"\F054"}.fa-chevron-up:before{content:"\F077"}.fa-child:before{content:"\F1AE"}.fa-chrome:before{content:"\F268"}.fa-chromecast:before{content:"\F838"}.fa-church:before{content:"\F51D"}.fa-circle:before{content:"\F111"}.fa-circle-notch:before{content:"\F1CE"}.fa-city:before{content:"\F64F"}.fa-clinic-medical:before{content:"\F7F2"}.fa-clipboard:before{content:"\F328"}.fa-clipboard-check:before{content:"\F46C"}.fa-clipboard-list:before{content:"\F46D"}.fa-clock:before{content:"\F017"}.fa-clone:before{content:"\F24D"}.fa-closed-captioning:before{content:"\F20A"}.fa-cloud:before{content:"\F0C2"}.fa-cloud-download-alt:before{content:"\F381"}.fa-cloud-meatball:before{content:"\F73B"}.fa-cloud-moon:before{content:"\F6C3"}.fa-cloud-moon-rain:before{content:"\F73C"}.fa-cloud-rain:before{content:"\F73D"}.fa-cloud-showers-heavy:before{content:"\F740"}.fa-cloud-sun:before{content:"\F6C4"}.fa-cloud-sun-rain:before{content:"\F743"}.fa-cloud-upload-alt:before{content:"\F382"}.fa-cloudscale:before{content:"\F383"}.fa-cloudsmith:before{content:"\F384"}.fa-cloudversify:before{content:"\F385"}.fa-cocktail:before{content:"\F561"}.fa-code:before{content:"\F121"}.fa-code-branch:before{content:"\F126"}.fa-codepen:before{content:"\F1CB"}.fa-codiepie:before{content:"\F284"}.fa-coffee:before{content:"\F0F4"}.fa-cog:before{content:"\F013"}.fa-cogs:before{content:"\F085"}.fa-coins:before{content:"\F51E"}.fa-columns:before{content:"\F0DB"}.fa-comment:before{content:"\F075"}.fa-comment-alt:before{content:"\F27A"}.fa-comment-dollar:before{content:"\F651"}.fa-comment-dots:before{content:"\F4AD"}.fa-comment-medical:before{content:"\F7F5"}.fa-comment-slash:before{content:"\F4B3"}.fa-comments:before{content:"\F086"}.fa-comments-dollar:before{content:"\F653"}.fa-compact-disc:before{content:"\F51F"}.fa-compass:before{content:"\F14E"}.fa-compress:before{content:"\F066"}.fa-compress-alt:before{content:"\F422"}.fa-compress-arrows-alt:before{content:"\F78C"}.fa-concierge-bell:before{content:"\F562"}.fa-confluence:before{content:"\F78D"}.fa-connectdevelop:before{content:"\F20E"}.fa-contao:before{content:"\F26D"}.fa-cookie:before{content:"\F563"}.fa-cookie-bite:before{content:"\F564"}.fa-copy:before{content:"\F0C5"}.fa-copyright:before{content:"\F1F9"}.fa-cotton-bureau:before{content:"\F89E"}.fa-couch:before{content:"\F4B8"}.fa-cpanel:before{content:"\F388"}.fa-creative-commons:before{content:"\F25E"}.fa-creative-commons-by:before{content:"\F4E7"}.fa-creative-commons-nc:before{content:"\F4E8"}.fa-creative-commons-nc-eu:before{content:"\F4E9"}.fa-creative-commons-nc-jp:before{content:"\F4EA"}.fa-creative-commons-nd:before{content:"\F4EB"}.fa-creative-commons-pd:before{content:"\F4EC"}.fa-creative-commons-pd-alt:before{content:"\F4ED"}.fa-creative-commons-remix:before{content:"\F4EE"}.fa-creative-commons-sa:before{content:"\F4EF"}.fa-creative-commons-sampling:before{content:"\F4F0"}.fa-creative-commons-sampling-plus:before{content:"\F4F1"}.fa-creative-commons-share:before{content:"\F4F2"}.fa-creative-commons-zero:before{content:"\F4F3"}.fa-credit-card:before{content:"\F09D"}.fa-critical-role:before{content:"\F6C9"}.fa-crop:before{content:"\F125"}.fa-crop-alt:before{content:"\F565"}.fa-cross:before{content:"\F654"}.fa-crosshairs:before{content:"\F05B"}.fa-crow:before{content:"\F520"}.fa-crown:before{content:"\F521"}.fa-crutch:before{content:"\F7F7"}.fa-css3:before{content:"\F13C"}.fa-css3-alt:before{content:"\F38B"}.fa-cube:before{content:"\F1B2"}.fa-cubes:before{content:"\F1B3"}.fa-cut:before{content:"\F0C4"}.fa-cuttlefish:before{content:"\F38C"}.fa-d-and-d:before{content:"\F38D"}.fa-d-and-d-beyond:before{content:"\F6CA"}.fa-dailymotion:before{content:"\F952"}.fa-dashcube:before{content:"\F210"}.fa-database:before{content:"\F1C0"}.fa-deaf:before{content:"\F2A4"}.fa-delicious:before{content:"\F1A5"}.fa-democrat:before{content:"\F747"}.fa-deploydog:before{content:"\F38E"}.fa-deskpro:before{content:"\F38F"}.fa-desktop:before{content:"\F108"}.fa-dev:before{content:"\F6CC"}.fa-deviantart:before{content:"\F1BD"}.fa-dharmachakra:before{content:"\F655"}.fa-dhl:before{content:"\F790"}.fa-diagnoses:before{content:"\F470"}.fa-diaspora:before{content:"\F791"}.fa-dice:before{content:"\F522"}.fa-dice-d20:before{content:"\F6CF"}.fa-dice-d6:before{content:"\F6D1"}.fa-dice-five:before{content:"\F523"}.fa-dice-four:before{content:"\F524"}.fa-dice-one:before{content:"\F525"}.fa-dice-six:before{content:"\F526"}.fa-dice-three:before{content:"\F527"}.fa-dice-two:before{content:"\F528"}.fa-digg:before{content:"\F1A6"}.fa-digital-ocean:before{content:"\F391"}.fa-digital-tachograph:before{content:"\F566"}.fa-directions:before{content:"\F5EB"}.fa-discord:before{content:"\F392"}.fa-discourse:before{content:"\F393"}.fa-disease:before{content:"\F7FA"}.fa-divide:before{content:"\F529"}.fa-dizzy:before{content:"\F567"}.fa-dna:before{content:"\F471"}.fa-dochub:before{content:"\F394"}.fa-docker:before{content:"\F395"}.fa-dog:before{content:"\F6D3"}.fa-dollar-sign:before{content:"\F155"}.fa-dolly:before{content:"\F472"}.fa-dolly-flatbed:before{content:"\F474"}.fa-donate:before{content:"\F4B9"}.fa-door-closed:before{content:"\F52A"}.fa-door-open:before{content:"\F52B"}.fa-dot-circle:before{content:"\F192"}.fa-dove:before{content:"\F4BA"}.fa-download:before{content:"\F019"}.fa-draft2digital:before{content:"\F396"}.fa-drafting-compass:before{content:"\F568"}.fa-dragon:before{content:"\F6D5"}.fa-draw-polygon:before{content:"\F5EE"}.fa-dribbble:before{content:"\F17D"}.fa-dribbble-square:before{content:"\F397"}.fa-dropbox:before{content:"\F16B"}.fa-drum:before{content:"\F569"}.fa-drum-steelpan:before{content:"\F56A"}.fa-drumstick-bite:before{content:"\F6D7"}.fa-drupal:before{content:"\F1A9"}.fa-dumbbell:before{content:"\F44B"}.fa-dumpster:before{content:"\F793"}.fa-dumpster-fire:before{content:"\F794"}.fa-dungeon:before{content:"\F6D9"}.fa-dyalog:before{content:"\F399"}.fa-earlybirds:before{content:"\F39A"}.fa-ebay:before{content:"\F4F4"}.fa-edge:before{content:"\F282"}.fa-edit:before{content:"\F044"}.fa-egg:before{content:"\F7FB"}.fa-eject:before{content:"\F052"}.fa-elementor:before{content:"\F430"}.fa-ellipsis-h:before{content:"\F141"}.fa-ellipsis-v:before{content:"\F142"}.fa-ello:before{content:"\F5F1"}.fa-ember:before{content:"\F423"}.fa-empire:before{content:"\F1D1"}.fa-envelope:before{content:"\F0E0"}.fa-envelope-open:before{content:"\F2B6"}.fa-envelope-open-text:before{content:"\F658"}.fa-envelope-square:before{content:"\F199"}.fa-envira:before{content:"\F299"}.fa-equals:before{content:"\F52C"}.fa-eraser:before{content:"\F12D"}.fa-erlang:before{content:"\F39D"}.fa-ethereum:before{content:"\F42E"}.fa-ethernet:before{content:"\F796"}.fa-etsy:before{content:"\F2D7"}.fa-euro-sign:before{content:"\F153"}.fa-evernote:before{content:"\F839"}.fa-exchange-alt:before{content:"\F362"}.fa-exclamation:before{content:"\F12A"}.fa-exclamation-circle:before{content:"\F06A"}.fa-exclamation-triangle:before{content:"\F071"}.fa-expand:before{content:"\F065"}.fa-expand-alt:before{content:"\F424"}.fa-expand-arrows-alt:before{content:"\F31E"}.fa-expeditedssl:before{content:"\F23E"}.fa-external-link-alt:before{content:"\F35D"}.fa-external-link-square-alt:before{content:"\F360"}.fa-eye:before{content:"\F06E"}.fa-eye-dropper:before{content:"\F1FB"}.fa-eye-slash:before{content:"\F070"}.fa-facebook:before{content:"\F09A"}.fa-facebook-f:before{content:"\F39E"}.fa-facebook-messenger:before{content:"\F39F"}.fa-facebook-square:before{content:"\F082"}.fa-fan:before{content:"\F863"}.fa-fantasy-flight-games:before{content:"\F6DC"}.fa-fast-backward:before{content:"\F049"}.fa-fast-forward:before{content:"\F050"}.fa-faucet:before{content:"\F905"}.fa-fax:before{content:"\F1AC"}.fa-feather:before{content:"\F52D"}.fa-feather-alt:before{content:"\F56B"}.fa-fedex:before{content:"\F797"}.fa-fedora:before{content:"\F798"}.fa-female:before{content:"\F182"}.fa-fighter-jet:before{content:"\F0FB"}.fa-figma:before{content:"\F799"}.fa-file:before{content:"\F15B"}.fa-file-alt:before{content:"\F15C"}.fa-file-archive:before{content:"\F1C6"}.fa-file-audio:before{content:"\F1C7"}.fa-file-code:before{content:"\F1C9"}.fa-file-contract:before{content:"\F56C"}.fa-file-csv:before{content:"\F6DD"}.fa-file-download:before{content:"\F56D"}.fa-file-excel:before{content:"\F1C3"}.fa-file-export:before{content:"\F56E"}.fa-file-image:before{content:"\F1C5"}.fa-file-import:before{content:"\F56F"}.fa-file-invoice:before{content:"\F570"}.fa-file-invoice-dollar:before{content:"\F571"}.fa-file-medical:before{content:"\F477"}.fa-file-medical-alt:before{content:"\F478"}.fa-file-pdf:before{content:"\F1C1"}.fa-file-powerpoint:before{content:"\F1C4"}.fa-file-prescription:before{content:"\F572"}.fa-file-signature:before{content:"\F573"}.fa-file-upload:before{content:"\F574"}.fa-file-video:before{content:"\F1C8"}.fa-file-word:before{content:"\F1C2"}.fa-fill:before{content:"\F575"}.fa-fill-drip:before{content:"\F576"}.fa-film:before{content:"\F008"}.fa-filter:before{content:"\F0B0"}.fa-fingerprint:before{content:"\F577"}.fa-fire:before{content:"\F06D"}.fa-fire-alt:before{content:"\F7E4"}.fa-fire-extinguisher:before{content:"\F134"}.fa-firefox:before{content:"\F269"}.fa-firefox-browser:before{content:"\F907"}.fa-first-aid:before{content:"\F479"}.fa-first-order:before{content:"\F2B0"}.fa-first-order-alt:before{content:"\F50A"}.fa-firstdraft:before{content:"\F3A1"}.fa-fish:before{content:"\F578"}.fa-fist-raised:before{content:"\F6DE"}.fa-flag:before{content:"\F024"}.fa-flag-checkered:before{content:"\F11E"}.fa-flag-usa:before{content:"\F74D"}.fa-flask:before{content:"\F0C3"}.fa-flickr:before{content:"\F16E"}.fa-flipboard:before{content:"\F44D"}.fa-flushed:before{content:"\F579"}.fa-fly:before{content:"\F417"}.fa-folder:before{content:"\F07B"}.fa-folder-minus:before{content:"\F65D"}.fa-folder-open:before{content:"\F07C"}.fa-folder-plus:before{content:"\F65E"}.fa-font:before{content:"\F031"}.fa-font-awesome:before{content:"\F2B4"}.fa-font-awesome-alt:before{content:"\F35C"}.fa-font-awesome-flag:before{content:"\F425"}.fa-font-awesome-logo-full:before{content:"\F4E6"}.fa-fonticons:before{content:"\F280"}.fa-fonticons-fi:before{content:"\F3A2"}.fa-football-ball:before{content:"\F44E"}.fa-fort-awesome:before{content:"\F286"}.fa-fort-awesome-alt:before{content:"\F3A3"}.fa-forumbee:before{content:"\F211"}.fa-forward:before{content:"\F04E"}.fa-foursquare:before{content:"\F180"}.fa-free-code-camp:before{content:"\F2C5"}.fa-freebsd:before{content:"\F3A4"}.fa-frog:before{content:"\F52E"}.fa-frown:before{content:"\F119"}.fa-frown-open:before{content:"\F57A"}.fa-fulcrum:before{content:"\F50B"}.fa-funnel-dollar:before{content:"\F662"}.fa-futbol:before{content:"\F1E3"}.fa-galactic-republic:before{content:"\F50C"}.fa-galactic-senate:before{content:"\F50D"}.fa-gamepad:before{content:"\F11B"}.fa-gas-pump:before{content:"\F52F"}.fa-gavel:before{content:"\F0E3"}.fa-gem:before{content:"\F3A5"}.fa-genderless:before{content:"\F22D"}.fa-get-pocket:before{content:"\F265"}.fa-gg:before{content:"\F260"}.fa-gg-circle:before{content:"\F261"}.fa-ghost:before{content:"\F6E2"}.fa-gift:before{content:"\F06B"}.fa-gifts:before{content:"\F79C"}.fa-git:before{content:"\F1D3"}.fa-git-alt:before{content:"\F841"}.fa-git-square:before{content:"\F1D2"}.fa-github:before{content:"\F09B"}.fa-github-alt:before{content:"\F113"}.fa-github-square:before{content:"\F092"}.fa-gitkraken:before{content:"\F3A6"}.fa-gitlab:before{content:"\F296"}.fa-gitter:before{content:"\F426"}.fa-glass-cheers:before{content:"\F79F"}.fa-glass-martini:before{content:"\F000"}.fa-glass-martini-alt:before{content:"\F57B"}.fa-glass-whiskey:before{content:"\F7A0"}.fa-glasses:before{content:"\F530"}.fa-glide:before{content:"\F2A5"}.fa-glide-g:before{content:"\F2A6"}.fa-globe:before{content:"\F0AC"}.fa-globe-africa:before{content:"\F57C"}.fa-globe-americas:before{content:"\F57D"}.fa-globe-asia:before{content:"\F57E"}.fa-globe-europe:before{content:"\F7A2"}.fa-gofore:before{content:"\F3A7"}.fa-golf-ball:before{content:"\F450"}.fa-goodreads:before{content:"\F3A8"}.fa-goodreads-g:before{content:"\F3A9"}.fa-google:before{content:"\F1A0"}.fa-google-drive:before{content:"\F3AA"}.fa-google-play:before{content:"\F3AB"}.fa-google-plus:before{content:"\F2B3"}.fa-google-plus-g:before{content:"\F0D5"}.fa-google-plus-square:before{content:"\F0D4"}.fa-google-wallet:before{content:"\F1EE"}.fa-gopuram:before{content:"\F664"}.fa-graduation-cap:before{content:"\F19D"}.fa-gratipay:before{content:"\F184"}.fa-grav:before{content:"\F2D6"}.fa-greater-than:before{content:"\F531"}.fa-greater-than-equal:before{content:"\F532"}.fa-grimace:before{content:"\F57F"}.fa-grin:before{content:"\F580"}.fa-grin-alt:before{content:"\F581"}.fa-grin-beam:before{content:"\F582"}.fa-grin-beam-sweat:before{content:"\F583"}.fa-grin-hearts:before{content:"\F584"}.fa-grin-squint:before{content:"\F585"}.fa-grin-squint-tears:before{content:"\F586"}.fa-grin-stars:before{content:"\F587"}.fa-grin-tears:before{content:"\F588"}.fa-grin-tongue:before{content:"\F589"}.fa-grin-tongue-squint:before{content:"\F58A"}.fa-grin-tongue-wink:before{content:"\F58B"}.fa-grin-wink:before{content:"\F58C"}.fa-grip-horizontal:before{content:"\F58D"}.fa-grip-lines:before{content:"\F7A4"}.fa-grip-lines-vertical:before{content:"\F7A5"}.fa-grip-vertical:before{content:"\F58E"}.fa-gripfire:before{content:"\F3AC"}.fa-grunt:before{content:"\F3AD"}.fa-guitar:before{content:"\F7A6"}.fa-gulp:before{content:"\F3AE"}.fa-h-square:before{content:"\F0FD"}.fa-hacker-news:before{content:"\F1D4"}.fa-hacker-news-square:before{content:"\F3AF"}.fa-hackerrank:before{content:"\F5F7"}.fa-hamburger:before{content:"\F805"}.fa-hammer:before{content:"\F6E3"}.fa-hamsa:before{content:"\F665"}.fa-hand-holding:before{content:"\F4BD"}.fa-hand-holding-heart:before{content:"\F4BE"}.fa-hand-holding-medical:before{content:"\F95C"}.fa-hand-holding-usd:before{content:"\F4C0"}.fa-hand-holding-water:before{content:"\F4C1"}.fa-hand-lizard:before{content:"\F258"}.fa-hand-middle-finger:before{content:"\F806"}.fa-hand-paper:before{content:"\F256"}.fa-hand-peace:before{content:"\F25B"}.fa-hand-point-down:before{content:"\F0A7"}.fa-hand-point-left:before{content:"\F0A5"}.fa-hand-point-right:before{content:"\F0A4"}.fa-hand-point-up:before{content:"\F0A6"}.fa-hand-pointer:before{content:"\F25A"}.fa-hand-rock:before{content:"\F255"}.fa-hand-scissors:before{content:"\F257"}.fa-hand-sparkles:before{content:"\F95D"}.fa-hand-spock:before{content:"\F259"}.fa-hands:before{content:"\F4C2"}.fa-hands-helping:before{content:"\F4C4"}.fa-hands-wash:before{content:"\F95E"}.fa-handshake:before{content:"\F2B5"}.fa-handshake-alt-slash:before{content:"\F95F"}.fa-handshake-slash:before{content:"\F960"}.fa-hanukiah:before{content:"\F6E6"}.fa-hard-hat:before{content:"\F807"}.fa-hashtag:before{content:"\F292"}.fa-hat-cowboy:before{content:"\F8C0"}.fa-hat-cowboy-side:before{content:"\F8C1"}.fa-hat-wizard:before{content:"\F6E8"}.fa-hdd:before{content:"\F0A0"}.fa-head-side-cough:before{content:"\F961"}.fa-head-side-cough-slash:before{content:"\F962"}.fa-head-side-mask:before{content:"\F963"}.fa-head-side-virus:before{content:"\F964"}.fa-heading:before{content:"\F1DC"}.fa-headphones:before{content:"\F025"}.fa-headphones-alt:before{content:"\F58F"}.fa-headset:before{content:"\F590"}.fa-heart:before{content:"\F004"}.fa-heart-broken:before{content:"\F7A9"}.fa-heartbeat:before{content:"\F21E"}.fa-helicopter:before{content:"\F533"}.fa-highlighter:before{content:"\F591"}.fa-hiking:before{content:"\F6EC"}.fa-hippo:before{content:"\F6ED"}.fa-hips:before{content:"\F452"}.fa-hire-a-helper:before{content:"\F3B0"}.fa-history:before{content:"\F1DA"}.fa-hockey-puck:before{content:"\F453"}.fa-holly-berry:before{content:"\F7AA"}.fa-home:before{content:"\F015"}.fa-hooli:before{content:"\F427"}.fa-hornbill:before{content:"\F592"}.fa-horse:before{content:"\F6F0"}.fa-horse-head:before{content:"\F7AB"}.fa-hospital:before{content:"\F0F8"}.fa-hospital-alt:before{content:"\F47D"}.fa-hospital-symbol:before{content:"\F47E"}.fa-hospital-user:before{content:"\F80D"}.fa-hot-tub:before{content:"\F593"}.fa-hotdog:before{content:"\F80F"}.fa-hotel:before{content:"\F594"}.fa-hotjar:before{content:"\F3B1"}.fa-hourglass:before{content:"\F254"}.fa-hourglass-end:before{content:"\F253"}.fa-hourglass-half:before{content:"\F252"}.fa-hourglass-start:before{content:"\F251"}.fa-house-damage:before{content:"\F6F1"}.fa-house-user:before{content:"\F965"}.fa-houzz:before{content:"\F27C"}.fa-hryvnia:before{content:"\F6F2"}.fa-html5:before{content:"\F13B"}.fa-hubspot:before{content:"\F3B2"}.fa-i-cursor:before{content:"\F246"}.fa-ice-cream:before{content:"\F810"}.fa-icicles:before{content:"\F7AD"}.fa-icons:before{content:"\F86D"}.fa-id-badge:before{content:"\F2C1"}.fa-id-card:before{content:"\F2C2"}.fa-id-card-alt:before{content:"\F47F"}.fa-ideal:before{content:"\F913"}.fa-igloo:before{content:"\F7AE"}.fa-image:before{content:"\F03E"}.fa-images:before{content:"\F302"}.fa-imdb:before{content:"\F2D8"}.fa-inbox:before{content:"\F01C"}.fa-indent:before{content:"\F03C"}.fa-industry:before{content:"\F275"}.fa-infinity:before{content:"\F534"}.fa-info:before{content:"\F129"}.fa-info-circle:before{content:"\F05A"}.fa-instagram:before{content:"\F16D"}.fa-instagram-square:before{content:"\F955"}.fa-intercom:before{content:"\F7AF"}.fa-internet-explorer:before{content:"\F26B"}.fa-invision:before{content:"\F7B0"}.fa-ioxhost:before{content:"\F208"}.fa-italic:before{content:"\F033"}.fa-itch-io:before{content:"\F83A"}.fa-itunes:before{content:"\F3B4"}.fa-itunes-note:before{content:"\F3B5"}.fa-java:before{content:"\F4E4"}.fa-jedi:before{content:"\F669"}.fa-jedi-order:before{content:"\F50E"}.fa-jenkins:before{content:"\F3B6"}.fa-jira:before{content:"\F7B1"}.fa-joget:before{content:"\F3B7"}.fa-joint:before{content:"\F595"}.fa-joomla:before{content:"\F1AA"}.fa-journal-whills:before{content:"\F66A"}.fa-js:before{content:"\F3B8"}.fa-js-square:before{content:"\F3B9"}.fa-jsfiddle:before{content:"\F1CC"}.fa-kaaba:before{content:"\F66B"}.fa-kaggle:before{content:"\F5FA"}.fa-key:before{content:"\F084"}.fa-keybase:before{content:"\F4F5"}.fa-keyboard:before{content:"\F11C"}.fa-keycdn:before{content:"\F3BA"}.fa-khanda:before{content:"\F66D"}.fa-kickstarter:before{content:"\F3BB"}.fa-kickstarter-k:before{content:"\F3BC"}.fa-kiss:before{content:"\F596"}.fa-kiss-beam:before{content:"\F597"}.fa-kiss-wink-heart:before{content:"\F598"}.fa-kiwi-bird:before{content:"\F535"}.fa-korvue:before{content:"\F42F"}.fa-landmark:before{content:"\F66F"}.fa-language:before{content:"\F1AB"}.fa-laptop:before{content:"\F109"}.fa-laptop-code:before{content:"\F5FC"}.fa-laptop-house:before{content:"\F966"}.fa-laptop-medical:before{content:"\F812"}.fa-laravel:before{content:"\F3BD"}.fa-lastfm:before{content:"\F202"}.fa-lastfm-square:before{content:"\F203"}.fa-laugh:before{content:"\F599"}.fa-laugh-beam:before{content:"\F59A"}.fa-laugh-squint:before{content:"\F59B"}.fa-laugh-wink:before{content:"\F59C"}.fa-layer-group:before{content:"\F5FD"}.fa-leaf:before{content:"\F06C"}.fa-leanpub:before{content:"\F212"}.fa-lemon:before{content:"\F094"}.fa-less:before{content:"\F41D"}.fa-less-than:before{content:"\F536"}.fa-less-than-equal:before{content:"\F537"}.fa-level-down-alt:before{content:"\F3BE"}.fa-level-up-alt:before{content:"\F3BF"}.fa-life-ring:before{content:"\F1CD"}.fa-lightbulb:before{content:"\F0EB"}.fa-line:before{content:"\F3C0"}.fa-link:before{content:"\F0C1"}.fa-linkedin:before{content:"\F08C"}.fa-linkedin-in:before{content:"\F0E1"}.fa-linode:before{content:"\F2B8"}.fa-linux:before{content:"\F17C"}.fa-lira-sign:before{content:"\F195"}.fa-list:before{content:"\F03A"}.fa-list-alt:before{content:"\F022"}.fa-list-ol:before{content:"\F0CB"}.fa-list-ul:before{content:"\F0CA"}.fa-location-arrow:before{content:"\F124"}.fa-lock:before{content:"\F023"}.fa-lock-open:before{content:"\F3C1"}.fa-long-arrow-alt-down:before{content:"\F309"}.fa-long-arrow-alt-left:before{content:"\F30A"}.fa-long-arrow-alt-right:before{content:"\F30B"}.fa-long-arrow-alt-up:before{content:"\F30C"}.fa-low-vision:before{content:"\F2A8"}.fa-luggage-cart:before{content:"\F59D"}.fa-lungs:before{content:"\F604"}.fa-lungs-virus:before{content:"\F967"}.fa-lyft:before{content:"\F3C3"}.fa-magento:before{content:"\F3C4"}.fa-magic:before{content:"\F0D0"}.fa-magnet:before{content:"\F076"}.fa-mail-bulk:before{content:"\F674"}.fa-mailchimp:before{content:"\F59E"}.fa-male:before{content:"\F183"}.fa-mandalorian:before{content:"\F50F"}.fa-map:before{content:"\F279"}.fa-map-marked:before{content:"\F59F"}.fa-map-marked-alt:before{content:"\F5A0"}.fa-map-marker:before{content:"\F041"}.fa-map-marker-alt:before{content:"\F3C5"}.fa-map-pin:before{content:"\F276"}.fa-map-signs:before{content:"\F277"}.fa-markdown:before{content:"\F60F"}.fa-marker:before{content:"\F5A1"}.fa-mars:before{content:"\F222"}.fa-mars-double:before{content:"\F227"}.fa-mars-stroke:before{content:"\F229"}.fa-mars-stroke-h:before{content:"\F22B"}.fa-mars-stroke-v:before{content:"\F22A"}.fa-mask:before{content:"\F6FA"}.fa-mastodon:before{content:"\F4F6"}.fa-maxcdn:before{content:"\F136"}.fa-mdb:before{content:"\F8CA"}.fa-medal:before{content:"\F5A2"}.fa-medapps:before{content:"\F3C6"}.fa-medium:before{content:"\F23A"}.fa-medium-m:before{content:"\F3C7"}.fa-medkit:before{content:"\F0FA"}.fa-medrt:before{content:"\F3C8"}.fa-meetup:before{content:"\F2E0"}.fa-megaport:before{content:"\F5A3"}.fa-meh:before{content:"\F11A"}.fa-meh-blank:before{content:"\F5A4"}.fa-meh-rolling-eyes:before{content:"\F5A5"}.fa-memory:before{content:"\F538"}.fa-mendeley:before{content:"\F7B3"}.fa-menorah:before{content:"\F676"}.fa-mercury:before{content:"\F223"}.fa-meteor:before{content:"\F753"}.fa-microblog:before{content:"\F91A"}.fa-microchip:before{content:"\F2DB"}.fa-microphone:before{content:"\F130"}.fa-microphone-alt:before{content:"\F3C9"}.fa-microphone-alt-slash:before{content:"\F539"}.fa-microphone-slash:before{content:"\F131"}.fa-microscope:before{content:"\F610"}.fa-microsoft:before{content:"\F3CA"}.fa-minus:before{content:"\F068"}.fa-minus-circle:before{content:"\F056"}.fa-minus-square:before{content:"\F146"}.fa-mitten:before{content:"\F7B5"}.fa-mix:before{content:"\F3CB"}.fa-mixcloud:before{content:"\F289"}.fa-mixer:before{content:"\F956"}.fa-mizuni:before{content:"\F3CC"}.fa-mobile:before{content:"\F10B"}.fa-mobile-alt:before{content:"\F3CD"}.fa-modx:before{content:"\F285"}.fa-monero:before{content:"\F3D0"}.fa-money-bill:before{content:"\F0D6"}.fa-money-bill-alt:before{content:"\F3D1"}.fa-money-bill-wave:before{content:"\F53A"}.fa-money-bill-wave-alt:before{content:"\F53B"}.fa-money-check:before{content:"\F53C"}.fa-money-check-alt:before{content:"\F53D"}.fa-monument:before{content:"\F5A6"}.fa-moon:before{content:"\F186"}.fa-mortar-pestle:before{content:"\F5A7"}.fa-mosque:before{content:"\F678"}.fa-motorcycle:before{content:"\F21C"}.fa-mountain:before{content:"\F6FC"}.fa-mouse:before{content:"\F8CC"}.fa-mouse-pointer:before{content:"\F245"}.fa-mug-hot:before{content:"\F7B6"}.fa-music:before{content:"\F001"}.fa-napster:before{content:"\F3D2"}.fa-neos:before{content:"\F612"}.fa-network-wired:before{content:"\F6FF"}.fa-neuter:before{content:"\F22C"}.fa-newspaper:before{content:"\F1EA"}.fa-nimblr:before{content:"\F5A8"}.fa-node:before{content:"\F419"}.fa-node-js:before{content:"\F3D3"}.fa-not-equal:before{content:"\F53E"}.fa-notes-medical:before{content:"\F481"}.fa-npm:before{content:"\F3D4"}.fa-ns8:before{content:"\F3D5"}.fa-nutritionix:before{content:"\F3D6"}.fa-object-group:before{content:"\F247"}.fa-object-ungroup:before{content:"\F248"}.fa-odnoklassniki:before{content:"\F263"}.fa-odnoklassniki-square:before{content:"\F264"}.fa-oil-can:before{content:"\F613"}.fa-old-republic:before{content:"\F510"}.fa-om:before{content:"\F679"}.fa-opencart:before{content:"\F23D"}.fa-openid:before{content:"\F19B"}.fa-opera:before{content:"\F26A"}.fa-optin-monster:before{content:"\F23C"}.fa-orcid:before{content:"\F8D2"}.fa-osi:before{content:"\F41A"}.fa-otter:before{content:"\F700"}.fa-outdent:before{content:"\F03B"}.fa-page4:before{content:"\F3D7"}.fa-pagelines:before{content:"\F18C"}.fa-pager:before{content:"\F815"}.fa-paint-brush:before{content:"\F1FC"}.fa-paint-roller:before{content:"\F5AA"}.fa-palette:before{content:"\F53F"}.fa-palfed:before{content:"\F3D8"}.fa-pallet:before{content:"\F482"}.fa-paper-plane:before{content:"\F1D8"}.fa-paperclip:before{content:"\F0C6"}.fa-parachute-box:before{content:"\F4CD"}.fa-paragraph:before{content:"\F1DD"}.fa-parking:before{content:"\F540"}.fa-passport:before{content:"\F5AB"}.fa-pastafarianism:before{content:"\F67B"}.fa-paste:before{content:"\F0EA"}.fa-patreon:before{content:"\F3D9"}.fa-pause:before{content:"\F04C"}.fa-pause-circle:before{content:"\F28B"}.fa-paw:before{content:"\F1B0"}.fa-paypal:before{content:"\F1ED"}.fa-peace:before{content:"\F67C"}.fa-pen:before{content:"\F304"}.fa-pen-alt:before{content:"\F305"}.fa-pen-fancy:before{content:"\F5AC"}.fa-pen-nib:before{content:"\F5AD"}.fa-pen-square:before{content:"\F14B"}.fa-pencil-alt:before{content:"\F303"}.fa-pencil-ruler:before{content:"\F5AE"}.fa-penny-arcade:before{content:"\F704"}.fa-people-arrows:before{content:"\F968"}.fa-people-carry:before{content:"\F4CE"}.fa-pepper-hot:before{content:"\F816"}.fa-percent:before{content:"\F295"}.fa-percentage:before{content:"\F541"}.fa-periscope:before{content:"\F3DA"}.fa-person-booth:before{content:"\F756"}.fa-phabricator:before{content:"\F3DB"}.fa-phoenix-framework:before{content:"\F3DC"}.fa-phoenix-squadron:before{content:"\F511"}.fa-phone:before{content:"\F095"}.fa-phone-alt:before{content:"\F879"}.fa-phone-slash:before{content:"\F3DD"}.fa-phone-square:before{content:"\F098"}.fa-phone-square-alt:before{content:"\F87B"}.fa-phone-volume:before{content:"\F2A0"}.fa-photo-video:before{content:"\F87C"}.fa-php:before{content:"\F457"}.fa-pied-piper:before{content:"\F2AE"}.fa-pied-piper-alt:before{content:"\F1A8"}.fa-pied-piper-hat:before{content:"\F4E5"}.fa-pied-piper-pp:before{content:"\F1A7"}.fa-pied-piper-square:before{content:"\F91E"}.fa-piggy-bank:before{content:"\F4D3"}.fa-pills:before{content:"\F484"}.fa-pinterest:before{content:"\F0D2"}.fa-pinterest-p:before{content:"\F231"}.fa-pinterest-square:before{content:"\F0D3"}.fa-pizza-slice:before{content:"\F818"}.fa-place-of-worship:before{content:"\F67F"}.fa-plane:before{content:"\F072"}.fa-plane-arrival:before{content:"\F5AF"}.fa-plane-departure:before{content:"\F5B0"}.fa-plane-slash:before{content:"\F969"}.fa-play:before{content:"\F04B"}.fa-play-circle:before{content:"\F144"}.fa-playstation:before{content:"\F3DF"}.fa-plug:before{content:"\F1E6"}.fa-plus:before{content:"\F067"}.fa-plus-circle:before{content:"\F055"}.fa-plus-square:before{content:"\F0FE"}.fa-podcast:before{content:"\F2CE"}.fa-poll:before{content:"\F681"}.fa-poll-h:before{content:"\F682"}.fa-poo:before{content:"\F2FE"}.fa-poo-storm:before{content:"\F75A"}.fa-poop:before{content:"\F619"}.fa-portrait:before{content:"\F3E0"}.fa-pound-sign:before{content:"\F154"}.fa-power-off:before{content:"\F011"}.fa-pray:before{content:"\F683"}.fa-praying-hands:before{content:"\F684"}.fa-prescription:before{content:"\F5B1"}.fa-prescription-bottle:before{content:"\F485"}.fa-prescription-bottle-alt:before{content:"\F486"}.fa-print:before{content:"\F02F"}.fa-procedures:before{content:"\F487"}.fa-product-hunt:before{content:"\F288"}.fa-project-diagram:before{content:"\F542"}.fa-pump-medical:before{content:"\F96A"}.fa-pump-soap:before{content:"\F96B"}.fa-pushed:before{content:"\F3E1"}.fa-puzzle-piece:before{content:"\F12E"}.fa-python:before{content:"\F3E2"}.fa-qq:before{content:"\F1D6"}.fa-qrcode:before{content:"\F029"}.fa-question:before{content:"\F128"}.fa-question-circle:before{content:"\F059"}.fa-quidditch:before{content:"\F458"}.fa-quinscape:before{content:"\F459"}.fa-quora:before{content:"\F2C4"}.fa-quote-left:before{content:"\F10D"}.fa-quote-right:before{content:"\F10E"}.fa-quran:before{content:"\F687"}.fa-r-project:before{content:"\F4F7"}.fa-radiation:before{content:"\F7B9"}.fa-radiation-alt:before{content:"\F7BA"}.fa-rainbow:before{content:"\F75B"}.fa-random:before{content:"\F074"}.fa-raspberry-pi:before{content:"\F7BB"}.fa-ravelry:before{content:"\F2D9"}.fa-react:before{content:"\F41B"}.fa-reacteurope:before{content:"\F75D"}.fa-readme:before{content:"\F4D5"}.fa-rebel:before{content:"\F1D0"}.fa-receipt:before{content:"\F543"}.fa-record-vinyl:before{content:"\F8D9"}.fa-recycle:before{content:"\F1B8"}.fa-red-river:before{content:"\F3E3"}.fa-reddit:before{content:"\F1A1"}.fa-reddit-alien:before{content:"\F281"}.fa-reddit-square:before{content:"\F1A2"}.fa-redhat:before{content:"\F7BC"}.fa-redo:before{content:"\F01E"}.fa-redo-alt:before{content:"\F2F9"}.fa-registered:before{content:"\F25D"}.fa-remove-format:before{content:"\F87D"}.fa-renren:before{content:"\F18B"}.fa-reply:before{content:"\F3E5"}.fa-reply-all:before{content:"\F122"}.fa-replyd:before{content:"\F3E6"}.fa-republican:before{content:"\F75E"}.fa-researchgate:before{content:"\F4F8"}.fa-resolving:before{content:"\F3E7"}.fa-restroom:before{content:"\F7BD"}.fa-retweet:before{content:"\F079"}.fa-rev:before{content:"\F5B2"}.fa-ribbon:before{content:"\F4D6"}.fa-ring:before{content:"\F70B"}.fa-road:before{content:"\F018"}.fa-robot:before{content:"\F544"}.fa-rocket:before{content:"\F135"}.fa-rocketchat:before{content:"\F3E8"}.fa-rockrms:before{content:"\F3E9"}.fa-route:before{content:"\F4D7"}.fa-rss:before{content:"\F09E"}.fa-rss-square:before{content:"\F143"}.fa-ruble-sign:before{content:"\F158"}.fa-ruler:before{content:"\F545"}.fa-ruler-combined:before{content:"\F546"}.fa-ruler-horizontal:before{content:"\F547"}.fa-ruler-vertical:before{content:"\F548"}.fa-running:before{content:"\F70C"}.fa-rupee-sign:before{content:"\F156"}.fa-sad-cry:before{content:"\F5B3"}.fa-sad-tear:before{content:"\F5B4"}.fa-safari:before{content:"\F267"}.fa-salesforce:before{content:"\F83B"}.fa-sass:before{content:"\F41E"}.fa-satellite:before{content:"\F7BF"}.fa-satellite-dish:before{content:"\F7C0"}.fa-save:before{content:"\F0C7"}.fa-schlix:before{content:"\F3EA"}.fa-school:before{content:"\F549"}.fa-screwdriver:before{content:"\F54A"}.fa-scribd:before{content:"\F28A"}.fa-scroll:before{content:"\F70E"}.fa-sd-card:before{content:"\F7C2"}.fa-search:before{content:"\F002"}.fa-search-dollar:before{content:"\F688"}.fa-search-location:before{content:"\F689"}.fa-search-minus:before{content:"\F010"}.fa-search-plus:before{content:"\F00E"}.fa-searchengin:before{content:"\F3EB"}.fa-seedling:before{content:"\F4D8"}.fa-sellcast:before{content:"\F2DA"}.fa-sellsy:before{content:"\F213"}.fa-server:before{content:"\F233"}.fa-servicestack:before{content:"\F3EC"}.fa-shapes:before{content:"\F61F"}.fa-share:before{content:"\F064"}.fa-share-alt:before{content:"\F1E0"}.fa-share-alt-square:before{content:"\F1E1"}.fa-share-square:before{content:"\F14D"}.fa-shekel-sign:before{content:"\F20B"}.fa-shield-alt:before{content:"\F3ED"}.fa-shield-virus:before{content:"\F96C"}.fa-ship:before{content:"\F21A"}.fa-shipping-fast:before{content:"\F48B"}.fa-shirtsinbulk:before{content:"\F214"}.fa-shoe-prints:before{content:"\F54B"}.fa-shopify:before{content:"\F957"}.fa-shopping-bag:before{content:"\F290"}.fa-shopping-basket:before{content:"\F291"}.fa-shopping-cart:before{content:"\F07A"}.fa-shopware:before{content:"\F5B5"}.fa-shower:before{content:"\F2CC"}.fa-shuttle-van:before{content:"\F5B6"}.fa-sign:before{content:"\F4D9"}.fa-sign-in-alt:before{content:"\F2F6"}.fa-sign-language:before{content:"\F2A7"}.fa-sign-out-alt:before{content:"\F2F5"}.fa-signal:before{content:"\F012"}.fa-signature:before{content:"\F5B7"}.fa-sim-card:before{content:"\F7C4"}.fa-simplybuilt:before{content:"\F215"}.fa-sistrix:before{content:"\F3EE"}.fa-sitemap:before{content:"\F0E8"}.fa-sith:before{content:"\F512"}.fa-skating:before{content:"\F7C5"}.fa-sketch:before{content:"\F7C6"}.fa-skiing:before{content:"\F7C9"}.fa-skiing-nordic:before{content:"\F7CA"}.fa-skull:before{content:"\F54C"}.fa-skull-crossbones:before{content:"\F714"}.fa-skyatlas:before{content:"\F216"}.fa-skype:before{content:"\F17E"}.fa-slack:before{content:"\F198"}.fa-slack-hash:before{content:"\F3EF"}.fa-slash:before{content:"\F715"}.fa-sleigh:before{content:"\F7CC"}.fa-sliders-h:before{content:"\F1DE"}.fa-slideshare:before{content:"\F1E7"}.fa-smile:before{content:"\F118"}.fa-smile-beam:before{content:"\F5B8"}.fa-smile-wink:before{content:"\F4DA"}.fa-smog:before{content:"\F75F"}.fa-smoking:before{content:"\F48D"}.fa-smoking-ban:before{content:"\F54D"}.fa-sms:before{content:"\F7CD"}.fa-snapchat:before{content:"\F2AB"}.fa-snapchat-ghost:before{content:"\F2AC"}.fa-snapchat-square:before{content:"\F2AD"}.fa-snowboarding:before{content:"\F7CE"}.fa-snowflake:before{content:"\F2DC"}.fa-snowman:before{content:"\F7D0"}.fa-snowplow:before{content:"\F7D2"}.fa-soap:before{content:"\F96E"}.fa-socks:before{content:"\F696"}.fa-solar-panel:before{content:"\F5BA"}.fa-sort:before{content:"\F0DC"}.fa-sort-alpha-down:before{content:"\F15D"}.fa-sort-alpha-down-alt:before{content:"\F881"}.fa-sort-alpha-up:before{content:"\F15E"}.fa-sort-alpha-up-alt:before{content:"\F882"}.fa-sort-amount-down:before{content:"\F160"}.fa-sort-amount-down-alt:before{content:"\F884"}.fa-sort-amount-up:before{content:"\F161"}.fa-sort-amount-up-alt:before{content:"\F885"}.fa-sort-down:before{content:"\F0DD"}.fa-sort-numeric-down:before{content:"\F162"}.fa-sort-numeric-down-alt:before{content:"\F886"}.fa-sort-numeric-up:before{content:"\F163"}.fa-sort-numeric-up-alt:before{content:"\F887"}.fa-sort-up:before{content:"\F0DE"}.fa-soundcloud:before{content:"\F1BE"}.fa-sourcetree:before{content:"\F7D3"}.fa-spa:before{content:"\F5BB"}.fa-space-shuttle:before{content:"\F197"}.fa-speakap:before{content:"\F3F3"}.fa-speaker-deck:before{content:"\F83C"}.fa-spell-check:before{content:"\F891"}.fa-spider:before{content:"\F717"}.fa-spinner:before{content:"\F110"}.fa-splotch:before{content:"\F5BC"}.fa-spotify:before{content:"\F1BC"}.fa-spray-can:before{content:"\F5BD"}.fa-square:before{content:"\F0C8"}.fa-square-full:before{content:"\F45C"}.fa-square-root-alt:before{content:"\F698"}.fa-squarespace:before{content:"\F5BE"}.fa-stack-exchange:before{content:"\F18D"}.fa-stack-overflow:before{content:"\F16C"}.fa-stackpath:before{content:"\F842"}.fa-stamp:before{content:"\F5BF"}.fa-star:before{content:"\F005"}.fa-star-and-crescent:before{content:"\F699"}.fa-star-half:before{content:"\F089"}.fa-star-half-alt:before{content:"\F5C0"}.fa-star-of-david:before{content:"\F69A"}.fa-star-of-life:before{content:"\F621"}.fa-staylinked:before{content:"\F3F5"}.fa-steam:before{content:"\F1B6"}.fa-steam-square:before{content:"\F1B7"}.fa-steam-symbol:before{content:"\F3F6"}.fa-step-backward:before{content:"\F048"}.fa-step-forward:before{content:"\F051"}.fa-stethoscope:before{content:"\F0F1"}.fa-sticker-mule:before{content:"\F3F7"}.fa-sticky-note:before{content:"\F249"}.fa-stop:before{content:"\F04D"}.fa-stop-circle:before{content:"\F28D"}.fa-stopwatch:before{content:"\F2F2"}.fa-stopwatch-20:before{content:"\F96F"}.fa-store:before{content:"\F54E"}.fa-store-alt:before{content:"\F54F"}.fa-store-alt-slash:before{content:"\F970"}.fa-store-slash:before{content:"\F971"}.fa-strava:before{content:"\F428"}.fa-stream:before{content:"\F550"}.fa-street-view:before{content:"\F21D"}.fa-strikethrough:before{content:"\F0CC"}.fa-stripe:before{content:"\F429"}.fa-stripe-s:before{content:"\F42A"}.fa-stroopwafel:before{content:"\F551"}.fa-studiovinari:before{content:"\F3F8"}.fa-stumbleupon:before{content:"\F1A4"}.fa-stumbleupon-circle:before{content:"\F1A3"}.fa-subscript:before{content:"\F12C"}.fa-subway:before{content:"\F239"}.fa-suitcase:before{content:"\F0F2"}.fa-suitcase-rolling:before{content:"\F5C1"}.fa-sun:before{content:"\F185"}.fa-superpowers:before{content:"\F2DD"}.fa-superscript:before{content:"\F12B"}.fa-supple:before{content:"\F3F9"}.fa-surprise:before{content:"\F5C2"}.fa-suse:before{content:"\F7D6"}.fa-swatchbook:before{content:"\F5C3"}.fa-swift:before{content:"\F8E1"}.fa-swimmer:before{content:"\F5C4"}.fa-swimming-pool:before{content:"\F5C5"}.fa-symfony:before{content:"\F83D"}.fa-synagogue:before{content:"\F69B"}.fa-sync:before{content:"\F021"}.fa-sync-alt:before{content:"\F2F1"}.fa-syringe:before{content:"\F48E"}.fa-table:before{content:"\F0CE"}.fa-table-tennis:before{content:"\F45D"}.fa-tablet:before{content:"\F10A"}.fa-tablet-alt:before{content:"\F3FA"}.fa-tablets:before{content:"\F490"}.fa-tachometer-alt:before{content:"\F3FD"}.fa-tag:before{content:"\F02B"}.fa-tags:before{content:"\F02C"}.fa-tape:before{content:"\F4DB"}.fa-tasks:before{content:"\F0AE"}.fa-taxi:before{content:"\F1BA"}.fa-teamspeak:before{content:"\F4F9"}.fa-teeth:before{content:"\F62E"}.fa-teeth-open:before{content:"\F62F"}.fa-telegram:before{content:"\F2C6"}.fa-telegram-plane:before{content:"\F3FE"}.fa-temperature-high:before{content:"\F769"}.fa-temperature-low:before{content:"\F76B"}.fa-tencent-weibo:before{content:"\F1D5"}.fa-tenge:before{content:"\F7D7"}.fa-terminal:before{content:"\F120"}.fa-text-height:before{content:"\F034"}.fa-text-width:before{content:"\F035"}.fa-th:before{content:"\F00A"}.fa-th-large:before{content:"\F009"}.fa-th-list:before{content:"\F00B"}.fa-the-red-yeti:before{content:"\F69D"}.fa-theater-masks:before{content:"\F630"}.fa-themeco:before{content:"\F5C6"}.fa-themeisle:before{content:"\F2B2"}.fa-thermometer:before{content:"\F491"}.fa-thermometer-empty:before{content:"\F2CB"}.fa-thermometer-full:before{content:"\F2C7"}.fa-thermometer-half:before{content:"\F2C9"}.fa-thermometer-quarter:before{content:"\F2CA"}.fa-thermometer-three-quarters:before{content:"\F2C8"}.fa-think-peaks:before{content:"\F731"}.fa-thumbs-down:before{content:"\F165"}.fa-thumbs-up:before{content:"\F164"}.fa-thumbtack:before{content:"\F08D"}.fa-ticket-alt:before{content:"\F3FF"}.fa-times:before{content:"\F00D"}.fa-times-circle:before{content:"\F057"}.fa-tint:before{content:"\F043"}.fa-tint-slash:before{content:"\F5C7"}.fa-tired:before{content:"\F5C8"}.fa-toggle-off:before{content:"\F204"}.fa-toggle-on:before{content:"\F205"}.fa-toilet:before{content:"\F7D8"}.fa-toilet-paper:before{content:"\F71E"}.fa-toilet-paper-slash:before{content:"\F972"}.fa-toolbox:before{content:"\F552"}.fa-tools:before{content:"\F7D9"}.fa-tooth:before{content:"\F5C9"}.fa-torah:before{content:"\F6A0"}.fa-torii-gate:before{content:"\F6A1"}.fa-tractor:before{content:"\F722"}.fa-trade-federation:before{content:"\F513"}.fa-trademark:before{content:"\F25C"}.fa-traffic-light:before{content:"\F637"}.fa-trailer:before{content:"\F941"}.fa-train:before{content:"\F238"}.fa-tram:before{content:"\F7DA"}.fa-transgender:before{content:"\F224"}.fa-transgender-alt:before{content:"\F225"}.fa-trash:before{content:"\F1F8"}.fa-trash-alt:before{content:"\F2ED"}.fa-trash-restore:before{content:"\F829"}.fa-trash-restore-alt:before{content:"\F82A"}.fa-tree:before{content:"\F1BB"}.fa-trello:before{content:"\F181"}.fa-tripadvisor:before{content:"\F262"}.fa-trophy:before{content:"\F091"}.fa-truck:before{content:"\F0D1"}.fa-truck-loading:before{content:"\F4DE"}.fa-truck-monster:before{content:"\F63B"}.fa-truck-moving:before{content:"\F4DF"}.fa-truck-pickup:before{content:"\F63C"}.fa-tshirt:before{content:"\F553"}.fa-tty:before{content:"\F1E4"}.fa-tumblr:before{content:"\F173"}.fa-tumblr-square:before{content:"\F174"}.fa-tv:before{content:"\F26C"}.fa-twitch:before{content:"\F1E8"}.fa-twitter:before{content:"\F099"}.fa-twitter-square:before{content:"\F081"}.fa-typo3:before{content:"\F42B"}.fa-uber:before{content:"\F402"}.fa-ubuntu:before{content:"\F7DF"}.fa-uikit:before{content:"\F403"}.fa-umbraco:before{content:"\F8E8"}.fa-umbrella:before{content:"\F0E9"}.fa-umbrella-beach:before{content:"\F5CA"}.fa-underline:before{content:"\F0CD"}.fa-undo:before{content:"\F0E2"}.fa-undo-alt:before{content:"\F2EA"}.fa-uniregistry:before{content:"\F404"}.fa-unity:before{content:"\F949"}.fa-universal-access:before{content:"\F29A"}.fa-university:before{content:"\F19C"}.fa-unlink:before{content:"\F127"}.fa-unlock:before{content:"\F09C"}.fa-unlock-alt:before{content:"\F13E"}.fa-untappd:before{content:"\F405"}.fa-upload:before{content:"\F093"}.fa-ups:before{content:"\F7E0"}.fa-usb:before{content:"\F287"}.fa-user:before{content:"\F007"}.fa-user-alt:before{content:"\F406"}.fa-user-alt-slash:before{content:"\F4FA"}.fa-user-astronaut:before{content:"\F4FB"}.fa-user-check:before{content:"\F4FC"}.fa-user-circle:before{content:"\F2BD"}.fa-user-clock:before{content:"\F4FD"}.fa-user-cog:before{content:"\F4FE"}.fa-user-edit:before{content:"\F4FF"}.fa-user-friends:before{content:"\F500"}.fa-user-graduate:before{content:"\F501"}.fa-user-injured:before{content:"\F728"}.fa-user-lock:before{content:"\F502"}.fa-user-md:before{content:"\F0F0"}.fa-user-minus:before{content:"\F503"}.fa-user-ninja:before{content:"\F504"}.fa-user-nurse:before{content:"\F82F"}.fa-user-plus:before{content:"\F234"}.fa-user-secret:before{content:"\F21B"}.fa-user-shield:before{content:"\F505"}.fa-user-slash:before{content:"\F506"}.fa-user-tag:before{content:"\F507"}.fa-user-tie:before{content:"\F508"}.fa-user-times:before{content:"\F235"}.fa-users:before{content:"\F0C0"}.fa-users-cog:before{content:"\F509"}.fa-usps:before{content:"\F7E1"}.fa-ussunnah:before{content:"\F407"}.fa-utensil-spoon:before{content:"\F2E5"}.fa-utensils:before{content:"\F2E7"}.fa-vaadin:before{content:"\F408"}.fa-vector-square:before{content:"\F5CB"}.fa-venus:before{content:"\F221"}.fa-venus-double:before{content:"\F226"}.fa-venus-mars:before{content:"\F228"}.fa-viacoin:before{content:"\F237"}.fa-viadeo:before{content:"\F2A9"}.fa-viadeo-square:before{content:"\F2AA"}.fa-vial:before{content:"\F492"}.fa-vials:before{content:"\F493"}.fa-viber:before{content:"\F409"}.fa-video:before{content:"\F03D"}.fa-video-slash:before{content:"\F4E2"}.fa-vihara:before{content:"\F6A7"}.fa-vimeo:before{content:"\F40A"}.fa-vimeo-square:before{content:"\F194"}.fa-vimeo-v:before{content:"\F27D"}.fa-vine:before{content:"\F1CA"}.fa-virus:before{content:"\F974"}.fa-virus-slash:before{content:"\F975"}.fa-viruses:before{content:"\F976"}.fa-vk:before{content:"\F189"}.fa-vnv:before{content:"\F40B"}.fa-voicemail:before{content:"\F897"}.fa-volleyball-ball:before{content:"\F45F"}.fa-volume-down:before{content:"\F027"}.fa-volume-mute:before{content:"\F6A9"}.fa-volume-off:before{content:"\F026"}.fa-volume-up:before{content:"\F028"}.fa-vote-yea:before{content:"\F772"}.fa-vr-cardboard:before{content:"\F729"}.fa-vuejs:before{content:"\F41F"}.fa-walking:before{content:"\F554"}.fa-wallet:before{content:"\F555"}.fa-warehouse:before{content:"\F494"}.fa-water:before{content:"\F773"}.fa-wave-square:before{content:"\F83E"}.fa-waze:before{content:"\F83F"}.fa-weebly:before{content:"\F5CC"}.fa-weibo:before{content:"\F18A"}.fa-weight:before{content:"\F496"}.fa-weight-hanging:before{content:"\F5CD"}.fa-weixin:before{content:"\F1D7"}.fa-whatsapp:before{content:"\F232"}.fa-whatsapp-square:before{content:"\F40C"}.fa-wheelchair:before{content:"\F193"}.fa-whmcs:before{content:"\F40D"}.fa-wifi:before{content:"\F1EB"}.fa-wikipedia-w:before{content:"\F266"}.fa-wind:before{content:"\F72E"}.fa-window-close:before{content:"\F410"}.fa-window-maximize:before{content:"\F2D0"}.fa-window-minimize:before{content:"\F2D1"}.fa-window-restore:before{content:"\F2D2"}.fa-windows:before{content:"\F17A"}.fa-wine-bottle:before{content:"\F72F"}.fa-wine-glass:before{content:"\F4E3"}.fa-wine-glass-alt:before{content:"\F5CE"}.fa-wix:before{content:"\F5CF"}.fa-wizards-of-the-coast:before{content:"\F730"}.fa-wolf-pack-battalion:before{content:"\F514"}.fa-won-sign:before{content:"\F159"}.fa-wordpress:before{content:"\F19A"}.fa-wordpress-simple:before{content:"\F411"}.fa-wpbeginner:before{content:"\F297"}.fa-wpexplorer:before{content:"\F2DE"}.fa-wpforms:before{content:"\F298"}.fa-wpressr:before{content:"\F3E4"}.fa-wrench:before{content:"\F0AD"}.fa-x-ray:before{content:"\F497"}.fa-xbox:before{content:"\F412"}.fa-xing:before{content:"\F168"}.fa-xing-square:before{content:"\F169"}.fa-y-combinator:before{content:"\F23B"}.fa-yahoo:before{content:"\F19E"}.fa-yammer:before{content:"\F840"}.fa-yandex:before{content:"\F413"}.fa-yandex-international:before{content:"\F414"}.fa-yarn:before{content:"\F7E3"}.fa-yelp:before{content:"\F1E9"}.fa-yen-sign:before{content:"\F157"}.fa-yin-yang:before{content:"\F6AD"}.fa-yoast:before{content:"\F2B1"}.fa-youtube:before{content:"\F167"}.fa-youtube-square:before{content:"\F431"}.fa-zhihu:before{content:"\F63F"}.sr-only-focusable:active,.sr-only-focusable:focus{margin:0}@font-face{font-family:Font Awesome\ 5 Brands;font-style:normal;font-weight:400;font-display:block;src:url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.eot?c1868c9545d2de1cf8488f1dadd8c9d0);src:url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.eot?c1868c9545d2de1cf8488f1dadd8c9d0?#iefix) format("embedded-opentype"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.woff2?a06da7f0950f9dd366fc9db9d56d618a) format("woff2"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.woff?ec3cfddedb8bebd2d7a3fdf511f7c1cc) format("woff"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.ttf?13685372945d816a2b474fc082fd9aaa) format("truetype"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-brands-400.svg?0cb5a5c0d251c109458c85c6afeffbaa#fontawesome) format("svg")}.fab{font-family:Font Awesome\ 5 Brands}@font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:400;font-display:block;src:url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.eot?261d666b0147c6c5cda07265f98b8f8c);src:url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.eot?261d666b0147c6c5cda07265f98b8f8c?#iefix) format("embedded-opentype"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.woff2?c20b5b7362d8d7bb7eddf94344ace33e) format("woff2"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.woff?f89ea91ecd1ca2db7e09baa2c4b156d1) format("woff"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.ttf?db78b9359171f24936b16d84f63af378) format("truetype"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-regular-400.svg?89ffa3aba80d30ee0a9371b25c968bbb#fontawesome) format("svg")}.fab,.far{font-weight:400}@font-face{font-family:Font Awesome\ 5 Free;font-style:normal;font-weight:900;font-display:block;src:url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.eot?a0369ea57eb6d3843d6474c035111f29);src:url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.eot?a0369ea57eb6d3843d6474c035111f29?#iefix) format("embedded-opentype"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.woff2?b15db15f746f29ffa02638cb455b8ec0) format("woff2"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.woff?bea989e82b07e9687c26fc58a4805021) format("woff"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.ttf?1ab236ed440ee51810c56bd16628aef0) format("truetype"),url(/fonts/vendor/@fortawesome/fontawesome-free/webfa-solid-900.svg?ec763292e583294612f124c0b0def500#fontawesome) format("svg")}.fa,.far,.fas{font-family:Font Awesome\ 5 Free}.fa,.fas{font-weight:900} +/*! + * OverlayScrollbars + * https://github.com/KingSora/OverlayScrollbars + * + * Version: 1.12.0 + * + * Copyright KingSora | Rene Haas. + * https://github.com/KingSora + * + * Released under the MIT license. + * Date: 05.04.2020 + */html.os-html,html.os-html>.os-host{display:block;overflow:hidden;box-sizing:border-box;height:100%!important;width:100%!important;min-width:100%!important;min-height:100%!important;margin:0!important;position:absolute!important}html.os-html>.os-host>.os-padding{position:absolute}body.os-dragging,body.os-dragging *{cursor:default}.os-host,.os-host-textarea{position:relative;overflow:visible!important;flex-direction:column;flex-wrap:nowrap;justify-content:flex-start;align-content:flex-start;-webkit-box-align:start;-ms-flex-align:start;-ms-grid-row-align:flex-start;align-items:flex-start}.os-host-flexbox{overflow:hidden!important;display:flex}.os-host-flexbox>.os-size-auto-observer{height:inherit!important}.os-host-flexbox>.os-content-glue{flex-grow:1;flex-shrink:0}.os-host-flexbox>.os-content-glue,.os-host-flexbox>.os-size-auto-observer{min-height:0;min-width:0;flex-grow:0;flex-shrink:1;flex-basis:auto}#os-dummy-scrollbar-size{position:fixed;opacity:0;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)";visibility:hidden;overflow:scroll;height:500px;width:500px}#os-dummy-scrollbar-size>div{width:200%;height:200%;margin:10px 0}#os-dummy-scrollbar-size:after,#os-dummy-scrollbar-size:before,.os-content:after,.os-content:before{content:"";display:table;width:.01px;height:.01px;line-height:0;font-size:0;flex-grow:0;flex-shrink:0;visibility:hidden}#os-dummy-scrollbar-size,.os-viewport{-ms-overflow-style:scrollbar!important}.os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size,.os-viewport-native-scrollbars-invisible.os-viewport{scrollbar-width:none!important}.os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar,.os-viewport-native-scrollbars-invisible#os-dummy-scrollbar-size::-webkit-scrollbar-corner,.os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar,.os-viewport-native-scrollbars-invisible.os-viewport::-webkit-scrollbar-corner{display:none!important;width:0!important;height:0!important;visibility:hidden!important;background:transparent!important}.os-content-glue{box-sizing:inherit;max-height:100%;max-width:100%;width:100%;pointer-events:none}.os-padding{box-sizing:inherit;direction:inherit;position:absolute;overflow:visible;padding:0;margin:0;left:0;top:0;bottom:0;right:0;width:auto!important;height:auto!important;z-index:1}.os-host-overflow>.os-padding,.os-viewport{overflow:hidden}.os-viewport{direction:inherit!important;box-sizing:inherit!important;resize:none!important;outline:none!important;position:absolute;top:0;left:0;bottom:0;right:0;padding:0;margin:0;-webkit-overflow-scrolling:touch}.os-content-arrange{position:absolute;z-index:-1;min-height:1px;min-width:1px;pointer-events:none}.os-content{direction:inherit;box-sizing:border-box!important;position:relative;display:block;height:100%;width:100%;visibility:visible}.os-content>.os-textarea{box-sizing:border-box!important;direction:inherit!important;background:transparent!important;outline:0 none transparent!important;overflow:hidden!important;position:absolute!important;display:block!important;top:0!important;left:0!important;margin:0!important;border-radius:0!important;float:none!important;-webkit-filter:none!important;filter:none!important;border:none!important;resize:none!important;transform:none!important;max-width:none!important;max-height:none!important;box-shadow:none!important;perspective:none!important;opacity:1!important;z-index:1!important;clip:auto!important;vertical-align:baseline!important;padding:0}.os-host-rtl>.os-padding>.os-viewport>.os-content>.os-textarea{right:0!important}.os-content>.os-textarea-cover{z-index:-1;pointer-events:none}.os-content>.os-textarea[wrap=off]{white-space:pre!important;margin:0!important}.os-text-inherit{font-family:inherit;font-size:inherit;font-weight:inherit;font-style:inherit;font-variant:inherit;text-transform:inherit;text-decoration:inherit;text-indent:inherit;text-align:inherit;text-shadow:inherit;text-overflow:inherit;letter-spacing:inherit;word-spacing:inherit;line-height:inherit;unicode-bidi:inherit;direction:inherit;color:inherit;cursor:text}.os-resize-observer,.os-resize-observer-host{box-sizing:inherit;display:block;visibility:hidden;position:absolute;top:0;left:0;height:100%;width:100%;overflow:hidden;pointer-events:none;z-index:-1}.os-resize-observer-host{padding:inherit;border:inherit;border-color:transparent;border-style:solid;box-sizing:border-box}.os-resize-observer-host>.os-resize-observer{height:200%;width:200%;padding:inherit;border:inherit;margin:0;display:block;box-sizing:content-box}.os-resize-observer-host.observed{display:flex;flex-direction:column;justify-content:flex-start;align-items:flex-start}.os-resize-observer-host.observed>.os-resize-observer{position:relative;flex-grow:1;flex-shrink:0;flex-basis:auto}.os-size-auto-observer{box-sizing:inherit!important;height:100%;width:inherit;max-width:1px;position:relative;float:left;max-height:1px;overflow:hidden;z-index:-1;padding:0;margin:0;pointer-events:none;flex-grow:inherit;flex-shrink:0;flex-basis:0}.os-size-auto-observer>.os-resize-observer{width:1000%;height:1000%;min-height:1px;min-width:1px}.os-resize-observer-item{position:absolute;top:0;right:0;bottom:0;left:0;overflow:hidden;z-index:-1;opacity:0;direction:ltr!important;flex:none!important}.os-resize-observer-item-final{position:absolute;left:0;top:0;transition:none!important;flex:none!important}.os-resize-observer{-webkit-animation-duration:1ms;animation-duration:1ms;-webkit-animation-name:os-resize-observer-dummy-animation;animation-name:os-resize-observer-dummy-animation}object.os-resize-observer{box-sizing:border-box!important}@-webkit-keyframes os-resize-observer-dummy-animation{0%{z-index:0}to{z-index:-1}}@keyframes os-resize-observer-dummy-animation{0%{z-index:0}to{z-index:-1}}.os-host-transition>.os-scrollbar,.os-host-transition>.os-scrollbar-corner{transition:opacity .3s,visibility .3s,top .3s,right .3s,bottom .3s,left .3s}html.os-html>.os-host>.os-scrollbar{position:absolute;z-index:999999}.os-scrollbar,.os-scrollbar-corner{position:absolute;opacity:1;-ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)";z-index:1}.os-scrollbar-corner{bottom:0;right:0}.os-scrollbar{pointer-events:none}.os-scrollbar-track{position:relative;padding:0!important;border:none!important}.os-scrollbar-handle,.os-scrollbar-track{pointer-events:auto;height:100%;width:100%}.os-scrollbar-handle{position:absolute}.os-scrollbar-handle-off,.os-scrollbar-track-off{pointer-events:none}.os-scrollbar.os-scrollbar-unusable,.os-scrollbar.os-scrollbar-unusable *{pointer-events:none!important}.os-scrollbar.os-scrollbar-unusable .os-scrollbar-handle{opacity:0!important}.os-scrollbar-horizontal{bottom:0;left:0}.os-scrollbar-vertical{top:0;right:0}.os-host-rtl>.os-scrollbar-horizontal{right:0}.os-host-rtl>.os-scrollbar-corner,.os-host-rtl>.os-scrollbar-vertical{right:auto;left:0}.os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-corner,.os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-corner,.os-host-scrollbar-horizontal-hidden>.os-scrollbar-horizontal,.os-host-scrollbar-vertical-hidden>.os-scrollbar-vertical,.os-padding+.os-scrollbar-corner,.os-scrollbar-auto-hidden,.os-scrollbar-horizontal+.os-scrollbar-vertical.os-scrollbar-auto-hidden+.os-scrollbar-corner,.os-scrollbar-horizontal.os-scrollbar-auto-hidden+.os-scrollbar-vertical+.os-scrollbar-corner,.os-scrollbar-horizontal.os-scrollbar-auto-hidden+.os-scrollbar-vertical.os-scrollbar-auto-hidden+.os-scrollbar-corner{opacity:0;visibility:hidden;pointer-events:none}.os-scrollbar-corner-resize-both{cursor:nwse-resize}.os-host-rtl>.os-scrollbar-corner-resize-both{cursor:nesw-resize}.os-scrollbar-corner-resize-horizontal{cursor:ew-resize}.os-scrollbar-corner-resize-vertical{cursor:ns-resize}.os-dragging .os-scrollbar-corner.os-scrollbar-corner-resize{cursor:default}.os-host-resize-disabled.os-host-scrollbar-horizontal-hidden>.os-scrollbar-vertical{top:0;bottom:0}.os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-horizontal,.os-host-rtl.os-host-resize-disabled.os-host-scrollbar-vertical-hidden>.os-scrollbar-horizontal{right:0;left:0}.os-scrollbar-corner.os-scrollbar-corner-resize,.os-scrollbar:hover{opacity:1!important;visibility:visible!important}.os-scrollbar-corner.os-scrollbar-corner-resize{background-image:url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxMCIgaGVpZ2h0PSIxMCI+PHBhdGggZD0iTTcuNDI0IDBhMS4zMSAxLjMxIDAgMDAtMS4zMSAxLjMxYzAgLjMuMTA0LjU3MS4yNzMuNzkyLjIxLjE0MS40NjYuMjE4LjczNy4yMThhMS4zMSAxLjMxIDAgMDAxLjMxLTEuMzFjMC0uMjcxLS4wNzctLjUyOC0uMjE4LS43MzdBMS4yOTggMS4yOTggMCAwMDcuNDI0IDB6bTAgMy4wODRhMS4zMSAxLjMxIDAgMDAtMS4zMSAxLjMxYzAgLjMuMTA0LjU3MS4yNzMuNzkyLjIxLjE0MS40NjYuMjE4LjczNy4yMThhMS4zMSAxLjMxIDAgMDAxLjMxLTEuMzFjMC0uMjcxLS4wNzctLjUyOC0uMjE4LS43MzdhMS4yOTggMS4yOTggMCAwMC0uNzkyLS4yNzN6bS0zLjA4NCAwYTEuMzEgMS4zMSAwIDAwLTEuMzEgMS4zMWMwIC4zLjEwNC41NzEuMjczLjc5Mi4yMDkuMTQxLjQ2NS4yMTguNzM3LjIxOGExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS4yNzEtLjA3Ny0uNTI4LS4yMTktLjczN2ExLjI5OCAxLjI5OCAwIDAwLS43OTEtLjI3M3ptLTMuMDMgMy4wM0ExLjMxIDEuMzEgMCAwMDAgNy40MjRjMCAuMy4xMDQuNTcxLjI3My43OTIuMjEuMTQxLjQ2Ni4yMTguNzM3LjIxOGExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS4yNzEtLjA3Ny0uNTI4LS4yMTgtLjczN2ExLjI5OCAxLjI5OCAwIDAwLS43OTItLjI3M3ptMy4wMyAwYTEuMzEgMS4zMSAwIDAwLTEuMzEgMS4zMWMwIC4zLjEwNC41NzEuMjczLjc5Mi4yMDkuMTQxLjQ2NS4yMTguNzM3LjIxOGExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS4yNzEtLjA3Ny0uNTI4LS4yMTktLjczN2ExLjI5OCAxLjI5OCAwIDAwLS43OTEtLjI3M3ptMy4wODQgMGExLjMxIDEuMzEgMCAwMC0xLjMxIDEuMzFjMCAuMy4xMDQuNTcxLjI3My43OTIuMjEuMTQxLjQ2Ni4yMTguNzM3LjIxOGExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS4yNzEtLjA3Ny0uNTI4LS4yMTgtLjczN2ExLjI5OCAxLjI5OCAwIDAwLS43OTItLjI3M3oiIGZpbGwtb3BhY2l0eT0iLjQ5NCIgZmlsbC1ydWxlPSJldmVub2RkIi8+PHBhdGggZD0iTTguMjE2LjI3M2MuMTQxLjIxLjIxOC40NjYuMjE4LjczN2ExLjMxIDEuMzEgMCAwMS0xLjMxIDEuMzFjLS4yNzEgMC0uNTI4LS4wNzctLjczNy0uMjE4LjI0LjMxMy42MTMuNTE4IDEuMDM3LjUxOGExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS40MjQtLjIwNS0uNzk4LS41MTgtMS4wMzd6bTAgMy4wODRjLjE0MS4yMS4yMTguNDY2LjIxOC43MzdhMS4zMSAxLjMxIDAgMDEtMS4zMSAxLjMxYy0uMjcxIDAtLjUyOC0uMDc3LS43MzctLjIxOC4yNC4zMTMuNjEzLjUxOSAxLjAzNy41MTlhMS4zMSAxLjMxIDAgMDAxLjMxLTEuMzFjMC0uNDI1LS4yMDUtLjc5OC0uNTE4LTEuMDM4em0tMy4wODUgMGMuMTQyLjIxLjIxOS40NjYuMjE5LjczN2ExLjMxIDEuMzEgMCAwMS0xLjMxIDEuMzFjLS4yNzIgMC0uNTI4LS4wNzctLjczNy0uMjE4LjI0LjMxMy42MTIuNTE5IDEuMDM3LjUxOWExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS40MjUtLjIwNS0uNzk4LS41MTktMS4wMzh6bS0zLjAzIDMuMDNjLjE0Mi4yMS4yMi40NjYuMjIuNzM3YTEuMzEgMS4zMSAwIDAxLTEuMzExIDEuMzFjLS4yNzEgMC0uNTI4LS4wNzctLjczNy0uMjE4LjI0LjMxMy42MTMuNTE4IDEuMDM3LjUxOGExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS40MjQtLjIwNS0uNzk4LS41MTgtMS4wMzd6bTMuMDMgMGMuMTQyLjIxLjIxOS40NjYuMjE5LjczN2ExLjMxIDEuMzEgMCAwMS0xLjMxIDEuMzFjLS4yNzIgMC0uNTI4LS4wNzctLjczNy0uMjE4LjI0LjMxMy42MTIuNTE4IDEuMDM3LjUxOGExLjMxIDEuMzEgMCAwMDEuMzEtMS4zMWMwLS40MjQtLjIwNS0uNzk4LS41MTktMS4wMzd6bTMuMDg1IDBjLjE0MS4yMS4yMTguNDY2LjIxOC43MzdhMS4zMSAxLjMxIDAgMDEtMS4zMSAxLjMxYy0uMjcxIDAtLjUyOC0uMDc3LS43MzctLjIxOC4yNC4zMTMuNjEzLjUxOCAxLjAzNy41MThhMS4zMSAxLjMxIDAgMDAxLjMxLTEuMzFjMC0uNDI0LS4yMDUtLjc5OC0uNTE4LTEuMDM3eiIgZmlsbD0iI2ZmZiIgZmlsbC1ydWxlPSJldmVub2RkIi8+PC9zdmc+);background-repeat:no-repeat;background-position:100% 100%;pointer-events:auto!important}.os-host-rtl>.os-scrollbar-corner.os-scrollbar-corner-resize{transform:scaleX(-1)}.os-host-overflow{overflow:hidden!important}.os-theme-none>.os-scrollbar-corner,.os-theme-none>.os-scrollbar-horizontal,.os-theme-none>.os-scrollbar-vertical{display:none!important}.os-theme-none>.os-scrollbar-corner-resize{display:block!important;min-width:10px;min-height:10px}.os-theme-dark>.os-scrollbar-horizontal,.os-theme-light>.os-scrollbar-horizontal{right:10px;height:10px}.os-theme-dark>.os-scrollbar-vertical,.os-theme-light>.os-scrollbar-vertical{bottom:10px;width:10px}.os-theme-dark.os-host-rtl>.os-scrollbar-horizontal,.os-theme-light.os-host-rtl>.os-scrollbar-horizontal{left:10px;right:0}.os-theme-dark>.os-scrollbar-corner,.os-theme-light>.os-scrollbar-corner{height:10px;width:10px;background-color:transparent}.os-theme-dark>.os-scrollbar,.os-theme-light>.os-scrollbar{padding:2px;box-sizing:border-box;background:transparent}.os-theme-dark>.os-scrollbar.os-scrollbar-unusable,.os-theme-dark>.os-scrollbar>.os-scrollbar-track,.os-theme-light>.os-scrollbar.os-scrollbar-unusable,.os-theme-light>.os-scrollbar>.os-scrollbar-track{background:transparent}.os-theme-dark>.os-scrollbar-horizontal>.os-scrollbar-track>.os-scrollbar-handle,.os-theme-light>.os-scrollbar-horizontal>.os-scrollbar-track>.os-scrollbar-handle{min-width:30px}.os-theme-dark>.os-scrollbar-vertical>.os-scrollbar-track>.os-scrollbar-handle,.os-theme-light>.os-scrollbar-vertical>.os-scrollbar-track>.os-scrollbar-handle{min-height:30px}.os-theme-dark.os-host-transition>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle,.os-theme-light.os-host-transition>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle{transition:background-color .3s}.os-theme-dark>.os-scrollbar>.os-scrollbar-track,.os-theme-dark>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle,.os-theme-light>.os-scrollbar>.os-scrollbar-track,.os-theme-light>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle{border-radius:10px}.os-theme-dark>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle{background:rgba(0,0,0,.4)}.os-theme-light>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle{background:hsla(0,0%,100%,.4)}.os-theme-dark>.os-scrollbar:hover>.os-scrollbar-track>.os-scrollbar-handle{background:rgba(0,0,0,.55)}.os-theme-light>.os-scrollbar:hover>.os-scrollbar-track>.os-scrollbar-handle{background:hsla(0,0%,100%,.55)}.os-theme-dark>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle.active{background:rgba(0,0,0,.7)}.os-theme-light>.os-scrollbar>.os-scrollbar-track>.os-scrollbar-handle.active{background:hsla(0,0%,100%,.7)}.os-theme-dark>.os-scrollbar-horizontal .os-scrollbar-handle:before,.os-theme-dark>.os-scrollbar-vertical .os-scrollbar-handle:before,.os-theme-light>.os-scrollbar-horizontal .os-scrollbar-handle:before,.os-theme-light>.os-scrollbar-vertical .os-scrollbar-handle:before{content:"";position:absolute;left:0;right:0;top:0;bottom:0;display:block}.os-theme-dark.os-host-scrollbar-horizontal-hidden>.os-scrollbar-horizontal .os-scrollbar-handle:before,.os-theme-dark.os-host-scrollbar-vertical-hidden>.os-scrollbar-vertical .os-scrollbar-handle:before,.os-theme-light.os-host-scrollbar-horizontal-hidden>.os-scrollbar-horizontal .os-scrollbar-handle:before,.os-theme-light.os-host-scrollbar-vertical-hidden>.os-scrollbar-vertical .os-scrollbar-handle:before{display:none}.os-theme-dark>.os-scrollbar-horizontal .os-scrollbar-handle:before,.os-theme-light>.os-scrollbar-horizontal .os-scrollbar-handle:before{top:-6px;bottom:-2px}.os-theme-dark>.os-scrollbar-vertical .os-scrollbar-handle:before,.os-theme-light>.os-scrollbar-vertical .os-scrollbar-handle:before{left:-6px;right:-2px}.os-host-rtl.os-theme-dark>.os-scrollbar-vertical .os-scrollbar-handle:before,.os-host-rtl.os-theme-light>.os-scrollbar-vertical .os-scrollbar-handle:before{right:-6px;left:-2px} +/*! + * icheck-bootstrap v3.0.1 (https://github.com/bantikyan/icheck-bootstrap) + * Copyright 2018 Hovhannes Bantikyan. + * Licensed under MIT (https://github.com/bantikyan/icheck-bootstrap/blob/master/LICENSE) + */[class*=icheck-]{min-height:22px;margin-top:6px!important;margin-bottom:6px!important;padding-left:0}.icheck-inline{display:inline-block}.icheck-inline+.icheck-inline{margin-left:.75rem;margin-top:6px}[class*=icheck-]>label{padding-left:29px!important;min-height:22px;line-height:22px;display:inline-block;position:relative;vertical-align:top;margin-bottom:0;font-weight:400;cursor:pointer}[class*=icheck-]>input:first-child{position:absolute!important;opacity:0;margin:0}[class*=icheck-]>input:first-child:disabled{cursor:default}[class*=icheck-]>input:first-child+input[type=hidden]+label:before,[class*=icheck-]>input:first-child+label:before{content:"";display:inline-block;position:absolute;width:22px;height:22px;border:1px solid #d3cfc8;border-radius:0;margin-left:-29px}[class*=icheck-]>input:first-child:checked+input[type=hidden]+label:after,[class*=icheck-]>input:first-child:checked+label:after{content:"";display:inline-block;position:absolute;top:0;left:0;width:7px;height:10px;border:2px solid #fff;border-top:none;border-left:none;transform:translate(7.75px,4.5px) rotate(45deg);-ms-transform:translate(7.75px,4.5px) rotate(45deg)}[class*=icheck-]>input[type=radio]:first-child+input[type=hidden]+label:before,[class*=icheck-]>input[type=radio]:first-child+label:before{border-radius:50%}[class*=icheck-]>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,[class*=icheck-]>input:first-child:not(:checked):not(:disabled):hover+label:before{border-width:2px}[class*=icheck-]>input:first-child:disabled+input[type=hidden]+label,[class*=icheck-]>input:first-child:disabled+input[type=hidden]+label:before,[class*=icheck-]>input:first-child:disabled+label,[class*=icheck-]>input:first-child:disabled+label:before{pointer-events:none;cursor:default;filter:alpha(opacity=65);box-shadow:none;opacity:.65}.icheck-default>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-default>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#adadad}.icheck-default>input:first-child:checked+input[type=hidden]+label:before,.icheck-default>input:first-child:checked+label:before{background-color:#e6e6e6;border-color:#adadad}.icheck-default>input:first-child:checked+input[type=hidden]+label:after,.icheck-default>input:first-child:checked+label:after{border-bottom-color:#333;border-right-color:#333}.icheck-primary>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-primary>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#2e6da4}.icheck-primary>input:first-child:checked+input[type=hidden]+label:before,.icheck-primary>input:first-child:checked+label:before{background-color:#337ab7;border-color:#2e6da4}.icheck-success>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-success>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#4cae4c}.icheck-success>input:first-child:checked+input[type=hidden]+label:before,.icheck-success>input:first-child:checked+label:before{background-color:#5cb85c;border-color:#4cae4c}.icheck-info>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-info>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#46b8da}.icheck-info>input:first-child:checked+input[type=hidden]+label:before,.icheck-info>input:first-child:checked+label:before{background-color:#5bc0de;border-color:#46b8da}.icheck-warning>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-warning>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#eea236}.icheck-warning>input:first-child:checked+input[type=hidden]+label:before,.icheck-warning>input:first-child:checked+label:before{background-color:#f0ad4e;border-color:#eea236}.icheck-danger>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-danger>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#d43f3a}.icheck-danger>input:first-child:checked+input[type=hidden]+label:before,.icheck-danger>input:first-child:checked+label:before{background-color:#d9534f;border-color:#d43f3a}.icheck-turquoise>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-turquoise>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#1abc9c}.icheck-turquoise>input:first-child:checked+input[type=hidden]+label:before,.icheck-turquoise>input:first-child:checked+label:before{background-color:#1abc9c;border-color:#1abc9c}.icheck-emerland>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-emerland>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#2ecc71}.icheck-emerland>input:first-child:checked+input[type=hidden]+label:before,.icheck-emerland>input:first-child:checked+label:before{background-color:#2ecc71;border-color:#2ecc71}.icheck-peterriver>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-peterriver>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#3498db}.icheck-peterriver>input:first-child:checked+input[type=hidden]+label:before,.icheck-peterriver>input:first-child:checked+label:before{background-color:#3498db;border-color:#3498db}.icheck-amethyst>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-amethyst>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#9b59b6}.icheck-amethyst>input:first-child:checked+input[type=hidden]+label:before,.icheck-amethyst>input:first-child:checked+label:before{background-color:#9b59b6;border-color:#9b59b6}.icheck-wetasphalt>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-wetasphalt>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#34495e}.icheck-wetasphalt>input:first-child:checked+input[type=hidden]+label:before,.icheck-wetasphalt>input:first-child:checked+label:before{background-color:#34495e;border-color:#34495e}.icheck-greensea>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-greensea>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#16a085}.icheck-greensea>input:first-child:checked+input[type=hidden]+label:before,.icheck-greensea>input:first-child:checked+label:before{background-color:#16a085;border-color:#16a085}.icheck-nephritis>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-nephritis>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#27ae60}.icheck-nephritis>input:first-child:checked+input[type=hidden]+label:before,.icheck-nephritis>input:first-child:checked+label:before{background-color:#27ae60;border-color:#27ae60}.icheck-belizehole>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-belizehole>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#2980b9}.icheck-belizehole>input:first-child:checked+input[type=hidden]+label:before,.icheck-belizehole>input:first-child:checked+label:before{background-color:#2980b9;border-color:#2980b9}.icheck-wisteria>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-wisteria>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#8e44ad}.icheck-wisteria>input:first-child:checked+input[type=hidden]+label:before,.icheck-wisteria>input:first-child:checked+label:before{background-color:#8e44ad;border-color:#8e44ad}.icheck-midnightblue>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-midnightblue>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#2c3e50}.icheck-midnightblue>input:first-child:checked+input[type=hidden]+label:before,.icheck-midnightblue>input:first-child:checked+label:before{background-color:#2c3e50;border-color:#2c3e50}.icheck-sunflower>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-sunflower>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#f1c40f}.icheck-sunflower>input:first-child:checked+input[type=hidden]+label:before,.icheck-sunflower>input:first-child:checked+label:before{background-color:#f1c40f;border-color:#f1c40f}.icheck-carrot>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-carrot>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#e67e22}.icheck-carrot>input:first-child:checked+input[type=hidden]+label:before,.icheck-carrot>input:first-child:checked+label:before{background-color:#e67e22;border-color:#e67e22}.icheck-alizarin>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-alizarin>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#e74c3c}.icheck-alizarin>input:first-child:checked+input[type=hidden]+label:before,.icheck-alizarin>input:first-child:checked+label:before{background-color:#e74c3c;border-color:#e74c3c}.icheck-clouds>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-clouds>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#ecf0f1}.icheck-clouds>input:first-child:checked+input[type=hidden]+label:before,.icheck-clouds>input:first-child:checked+label:before{background-color:#ecf0f1;border-color:#ecf0f1}.icheck-clouds>input:first-child:checked+input[type=hidden]+label:after,.icheck-clouds>input:first-child:checked+label:after{border-bottom-color:#95a5a6;border-right-color:#95a5a6}.icheck-concrete>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-concrete>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#95a5a6}.icheck-concrete>input:first-child:checked+input[type=hidden]+label:before,.icheck-concrete>input:first-child:checked+label:before{background-color:#95a5a6;border-color:#95a5a6}.icheck-orange>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-orange>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#f39c12}.icheck-orange>input:first-child:checked+input[type=hidden]+label:before,.icheck-orange>input:first-child:checked+label:before{background-color:#f39c12;border-color:#f39c12}.icheck-pumpkin>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-pumpkin>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#d35400}.icheck-pumpkin>input:first-child:checked+input[type=hidden]+label:before,.icheck-pumpkin>input:first-child:checked+label:before{background-color:#d35400;border-color:#d35400}.icheck-pomegranate>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-pomegranate>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#c0392b}.icheck-pomegranate>input:first-child:checked+input[type=hidden]+label:before,.icheck-pomegranate>input:first-child:checked+label:before{background-color:#c0392b;border-color:#c0392b}.icheck-silver>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-silver>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#bdc3c7}.icheck-silver>input:first-child:checked+input[type=hidden]+label:before,.icheck-silver>input:first-child:checked+label:before{background-color:#bdc3c7;border-color:#bdc3c7}.icheck-asbestos>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-asbestos>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#7f8c8d}.icheck-asbestos>input:first-child:checked+input[type=hidden]+label:before,.icheck-asbestos>input:first-child:checked+label:before{background-color:#7f8c8d;border-color:#7f8c8d}/*! + * AdminLTE v3.0.5 + * Author: Colorlib + * Website: AdminLTE.io + * License: Open source - MIT + */ +/*! + * Bootstrap v4.4.1 (https://getbootstrap.com/) + * Copyright 2011-2019 The Bootstrap Authors + * Copyright 2011-2019 Twitter, Inc. + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE) + */:root{--blue:#007bff;--indigo:#6610f2;--purple:#6f42c1;--pink:#e83e8c;--red:#dc3545;--orange:#fd7e14;--yellow:#ffc107;--green:#28a745;--teal:#20c997;--cyan:#17a2b8;--white:#fff;--gray:#6c757d;--gray-dark:#343a40;--primary:#007bff;--secondary:#6c757d;--success:#28a745;--info:#17a2b8;--warning:#ffc107;--danger:#dc3545;--light:#f8f9fa;--dark:#343a40;--breakpoint-xs:0;--breakpoint-sm:576px;--breakpoint-md:768px;--breakpoint-lg:992px;--breakpoint-xl:1200px;--font-family-sans-serif:"Source Sans Pro",-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol";--font-family-monospace:SFMono-Regular,Menlo,Monaco,Consolas,"Liberation Mono","Courier New",monospace}*,:after,:before{box-sizing:border-box}html{font-family:sans-serif;line-height:1.15;-webkit-text-size-adjust:100%;-webkit-tap-highlight-color:rgba(0,0,0,0)}article,aside,figcaption,figure,footer,header,hgroup,main,nav,section{display:block}body{margin:0;font-family:Source Sans Pro,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-size:1rem;font-weight:400;line-height:1.5;color:#212529;text-align:left;background-color:#fff}[tabindex="-1"]:focus:not(:focus-visible){outline:0!important}hr{box-sizing:content-box;height:0;overflow:visible}h1,h2,h3,h4,h5,h6{margin-top:0;margin-bottom:.5rem}p{margin-top:0;margin-bottom:1rem}abbr[data-original-title],abbr[title]{text-decoration:underline;-webkit-text-decoration:underline dotted;text-decoration:underline dotted;cursor:help;border-bottom:0;-webkit-text-decoration-skip-ink:none;text-decoration-skip-ink:none}address{font-style:normal;line-height:inherit}address,dl,ol,ul{margin-bottom:1rem}dl,ol,ul{margin-top:0}ol ol,ol ul,ul ol,ul ul{margin-bottom:0}dt{font-weight:700}dd{margin-bottom:.5rem;margin-left:0}blockquote{margin:0 0 1rem}b,strong{font-weight:bolder}small{font-size:80%}sub,sup{position:relative;font-size:75%;line-height:0;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}a{color:#007bff;background-color:transparent}a,a:hover{text-decoration:none}a:hover{color:#0056b3}a:not([href]),a:not([href]):hover{color:inherit;text-decoration:none}code,kbd,pre,samp{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace;font-size:1em}pre{margin-top:0;margin-bottom:1rem;overflow:auto}figure{margin:0 0 1rem}img{border-style:none}img,svg{vertical-align:middle}svg{overflow:hidden}table{border-collapse:collapse}caption{padding-top:.75rem;padding-bottom:.75rem;color:#6c757d;text-align:left;caption-side:bottom}th{text-align:inherit}label{display:inline-block;margin-bottom:.5rem}button{border-radius:0}button:focus{outline:1px dotted;outline:5px auto -webkit-focus-ring-color}button,input,optgroup,select,textarea{margin:0;font-family:inherit;font-size:inherit;line-height:inherit}button,input{overflow:visible}button,select{text-transform:none}select{word-wrap:normal}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]:not(:disabled),[type=reset]:not(:disabled),[type=submit]:not(:disabled),button:not(:disabled){cursor:pointer}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{padding:0;border-style:none}input[type=checkbox],input[type=radio]{box-sizing:border-box;padding:0}input[type=date],input[type=datetime-local],input[type=month],input[type=time]{-webkit-appearance:listbox}textarea{overflow:auto;resize:vertical}fieldset{min-width:0;padding:0;margin:0;border:0}legend{display:block;width:100%;max-width:100%;padding:0;margin-bottom:.5rem;font-size:1.5rem;line-height:inherit;color:inherit;white-space:normal}progress{vertical-align:baseline}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{outline-offset:-2px;-webkit-appearance:none}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{font:inherit;-webkit-appearance:button}output{display:inline-block}summary{display:list-item;cursor:pointer}template{display:none}[hidden]{display:none!important}.h1,.h2,.h3,.h4,.h5,.h6,h1,h2,h3,h4,h5,h6{margin-bottom:.5rem;font-family:inherit;font-weight:500;line-height:1.2;color:inherit}.h1,h1{font-size:2.5rem}.h2,h2{font-size:2rem}.h3,h3{font-size:1.75rem}.h4,h4{font-size:1.5rem}.h5,h5{font-size:1.25rem}.h6,h6{font-size:1rem}.lead{font-size:1.25rem;font-weight:300}.display-1{font-size:6rem}.display-1,.display-2{font-weight:300;line-height:1.2}.display-2{font-size:5.5rem}.display-3{font-size:4.5rem}.display-3,.display-4{font-weight:300;line-height:1.2}.display-4{font-size:3.5rem}hr{margin-top:1rem;margin-bottom:1rem;border:0;border-top:1px solid rgba(0,0,0,.1)}.small,small{font-size:80%;font-weight:400}.mark,mark{padding:.2em;background-color:#fcf8e3}.list-inline,.list-unstyled{padding-left:0;list-style:none}.list-inline-item{display:inline-block}.list-inline-item:not(:last-child){margin-right:.5rem}.initialism{font-size:90%;text-transform:uppercase}.blockquote{margin-bottom:1rem;font-size:1.25rem}.blockquote-footer{display:block;font-size:80%;color:#6c757d}.blockquote-footer:before{content:"\2014\A0"}.img-fluid,.img-thumbnail{max-width:100%;height:auto}.img-thumbnail{padding:.25rem;background-color:#fff;border:1px solid #dee2e6;border-radius:.25rem;box-shadow:0 1px 2px rgba(0,0,0,.075)}.figure{display:inline-block}.figure-img{margin-bottom:.5rem;line-height:1}.figure-caption{font-size:90%;color:#6c757d}code{font-size:87.5%;color:#e83e8c;word-wrap:break-word}a>code{color:inherit}kbd{padding:.2rem .4rem;font-size:87.5%;color:#fff;background-color:#212529;border-radius:.2rem;box-shadow:inset 0 -.1rem 0 rgba(0,0,0,.25)}kbd kbd{padding:0;font-size:100%;font-weight:700;box-shadow:none}pre{display:block;font-size:87.5%;color:#212529}pre code{font-size:inherit;color:inherit;word-break:normal}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{width:100%;padding-right:7.5px;padding-left:7.5px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container{max-width:540px}}@media (min-width:768px){.container{max-width:720px}}@media (min-width:992px){.container{max-width:960px}}@media (min-width:1200px){.container{max-width:1140px}}.container-fluid,.container-lg,.container-md,.container-sm,.container-xl{width:100%;padding-right:7.5px;padding-left:7.5px;margin-right:auto;margin-left:auto}@media (min-width:576px){.container,.container-sm{max-width:540px}}@media (min-width:768px){.container,.container-md,.container-sm{max-width:720px}}@media (min-width:992px){.container,.container-lg,.container-md,.container-sm{max-width:960px}}@media (min-width:1200px){.container,.container-lg,.container-md,.container-sm,.container-xl{max-width:1140px}}.row{display:flex;flex-wrap:wrap;margin-right:-7.5px;margin-left:-7.5px}.no-gutters{margin-right:0;margin-left:0}.no-gutters>.col,.no-gutters>[class*=col-]{padding-right:0;padding-left:0}.col,.col-1,.col-2,.col-3,.col-4,.col-5,.col-6,.col-7,.col-8,.col-9,.col-10,.col-11,.col-12,.col-auto,.col-lg,.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12,.col-lg-auto,.col-md,.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12,.col-md-auto,.col-sm,.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12,.col-sm-auto,.col-xl,.col-xl-1,.col-xl-2,.col-xl-3,.col-xl-4,.col-xl-5,.col-xl-6,.col-xl-7,.col-xl-8,.col-xl-9,.col-xl-10,.col-xl-11,.col-xl-12,.col-xl-auto{position:relative;width:100%;padding-right:7.5px;padding-left:7.5px}.col{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-1>*{flex:0 0 100%;max-width:100%}.row-cols-2>*{flex:0 0 50%;max-width:50%}.row-cols-3>*{flex:0 0 33.333333%;max-width:33.333333%}.row-cols-4>*{flex:0 0 25%;max-width:25%}.row-cols-5>*{flex:0 0 20%;max-width:20%}.row-cols-6>*{flex:0 0 16.666667%;max-width:16.666667%}.col-auto{flex:0 0 auto;width:auto;max-width:100%}.col-1{flex:0 0 8.333333%;max-width:8.333333%}.col-2{flex:0 0 16.666667%;max-width:16.666667%}.col-3{flex:0 0 25%;max-width:25%}.col-4{flex:0 0 33.333333%;max-width:33.333333%}.col-5{flex:0 0 41.666667%;max-width:41.666667%}.col-6{flex:0 0 50%;max-width:50%}.col-7{flex:0 0 58.333333%;max-width:58.333333%}.col-8{flex:0 0 66.666667%;max-width:66.666667%}.col-9{flex:0 0 75%;max-width:75%}.col-10{flex:0 0 83.333333%;max-width:83.333333%}.col-11{flex:0 0 91.666667%;max-width:91.666667%}.col-12{flex:0 0 100%;max-width:100%}.order-first{order:-1}.order-last{order:13}.order-0{order:0}.order-1{order:1}.order-2{order:2}.order-3{order:3}.order-4{order:4}.order-5{order:5}.order-6{order:6}.order-7{order:7}.order-8{order:8}.order-9{order:9}.order-10{order:10}.order-11{order:11}.order-12{order:12}.offset-1{margin-left:8.333333%}.offset-2{margin-left:16.666667%}.offset-3{margin-left:25%}.offset-4{margin-left:33.333333%}.offset-5{margin-left:41.666667%}.offset-6{margin-left:50%}.offset-7{margin-left:58.333333%}.offset-8{margin-left:66.666667%}.offset-9{margin-left:75%}.offset-10{margin-left:83.333333%}.offset-11{margin-left:91.666667%}@media (min-width:576px){.col-sm{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-sm-1>*{flex:0 0 100%;max-width:100%}.row-cols-sm-2>*{flex:0 0 50%;max-width:50%}.row-cols-sm-3>*{flex:0 0 33.333333%;max-width:33.333333%}.row-cols-sm-4>*{flex:0 0 25%;max-width:25%}.row-cols-sm-5>*{flex:0 0 20%;max-width:20%}.row-cols-sm-6>*{flex:0 0 16.666667%;max-width:16.666667%}.col-sm-auto{flex:0 0 auto;width:auto;max-width:100%}.col-sm-1{flex:0 0 8.333333%;max-width:8.333333%}.col-sm-2{flex:0 0 16.666667%;max-width:16.666667%}.col-sm-3{flex:0 0 25%;max-width:25%}.col-sm-4{flex:0 0 33.333333%;max-width:33.333333%}.col-sm-5{flex:0 0 41.666667%;max-width:41.666667%}.col-sm-6{flex:0 0 50%;max-width:50%}.col-sm-7{flex:0 0 58.333333%;max-width:58.333333%}.col-sm-8{flex:0 0 66.666667%;max-width:66.666667%}.col-sm-9{flex:0 0 75%;max-width:75%}.col-sm-10{flex:0 0 83.333333%;max-width:83.333333%}.col-sm-11{flex:0 0 91.666667%;max-width:91.666667%}.col-sm-12{flex:0 0 100%;max-width:100%}.order-sm-first{order:-1}.order-sm-last{order:13}.order-sm-0{order:0}.order-sm-1{order:1}.order-sm-2{order:2}.order-sm-3{order:3}.order-sm-4{order:4}.order-sm-5{order:5}.order-sm-6{order:6}.order-sm-7{order:7}.order-sm-8{order:8}.order-sm-9{order:9}.order-sm-10{order:10}.order-sm-11{order:11}.order-sm-12{order:12}.offset-sm-0{margin-left:0}.offset-sm-1{margin-left:8.333333%}.offset-sm-2{margin-left:16.666667%}.offset-sm-3{margin-left:25%}.offset-sm-4{margin-left:33.333333%}.offset-sm-5{margin-left:41.666667%}.offset-sm-6{margin-left:50%}.offset-sm-7{margin-left:58.333333%}.offset-sm-8{margin-left:66.666667%}.offset-sm-9{margin-left:75%}.offset-sm-10{margin-left:83.333333%}.offset-sm-11{margin-left:91.666667%}}@media (min-width:768px){.col-md{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-md-1>*{flex:0 0 100%;max-width:100%}.row-cols-md-2>*{flex:0 0 50%;max-width:50%}.row-cols-md-3>*{flex:0 0 33.333333%;max-width:33.333333%}.row-cols-md-4>*{flex:0 0 25%;max-width:25%}.row-cols-md-5>*{flex:0 0 20%;max-width:20%}.row-cols-md-6>*{flex:0 0 16.666667%;max-width:16.666667%}.col-md-auto{flex:0 0 auto;width:auto;max-width:100%}.col-md-1{flex:0 0 8.333333%;max-width:8.333333%}.col-md-2{flex:0 0 16.666667%;max-width:16.666667%}.col-md-3{flex:0 0 25%;max-width:25%}.col-md-4{flex:0 0 33.333333%;max-width:33.333333%}.col-md-5{flex:0 0 41.666667%;max-width:41.666667%}.col-md-6{flex:0 0 50%;max-width:50%}.col-md-7{flex:0 0 58.333333%;max-width:58.333333%}.col-md-8{flex:0 0 66.666667%;max-width:66.666667%}.col-md-9{flex:0 0 75%;max-width:75%}.col-md-10{flex:0 0 83.333333%;max-width:83.333333%}.col-md-11{flex:0 0 91.666667%;max-width:91.666667%}.col-md-12{flex:0 0 100%;max-width:100%}.order-md-first{order:-1}.order-md-last{order:13}.order-md-0{order:0}.order-md-1{order:1}.order-md-2{order:2}.order-md-3{order:3}.order-md-4{order:4}.order-md-5{order:5}.order-md-6{order:6}.order-md-7{order:7}.order-md-8{order:8}.order-md-9{order:9}.order-md-10{order:10}.order-md-11{order:11}.order-md-12{order:12}.offset-md-0{margin-left:0}.offset-md-1{margin-left:8.333333%}.offset-md-2{margin-left:16.666667%}.offset-md-3{margin-left:25%}.offset-md-4{margin-left:33.333333%}.offset-md-5{margin-left:41.666667%}.offset-md-6{margin-left:50%}.offset-md-7{margin-left:58.333333%}.offset-md-8{margin-left:66.666667%}.offset-md-9{margin-left:75%}.offset-md-10{margin-left:83.333333%}.offset-md-11{margin-left:91.666667%}}@media (min-width:992px){.col-lg{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-lg-1>*{flex:0 0 100%;max-width:100%}.row-cols-lg-2>*{flex:0 0 50%;max-width:50%}.row-cols-lg-3>*{flex:0 0 33.333333%;max-width:33.333333%}.row-cols-lg-4>*{flex:0 0 25%;max-width:25%}.row-cols-lg-5>*{flex:0 0 20%;max-width:20%}.row-cols-lg-6>*{flex:0 0 16.666667%;max-width:16.666667%}.col-lg-auto{flex:0 0 auto;width:auto;max-width:100%}.col-lg-1{flex:0 0 8.333333%;max-width:8.333333%}.col-lg-2{flex:0 0 16.666667%;max-width:16.666667%}.col-lg-3{flex:0 0 25%;max-width:25%}.col-lg-4{flex:0 0 33.333333%;max-width:33.333333%}.col-lg-5{flex:0 0 41.666667%;max-width:41.666667%}.col-lg-6{flex:0 0 50%;max-width:50%}.col-lg-7{flex:0 0 58.333333%;max-width:58.333333%}.col-lg-8{flex:0 0 66.666667%;max-width:66.666667%}.col-lg-9{flex:0 0 75%;max-width:75%}.col-lg-10{flex:0 0 83.333333%;max-width:83.333333%}.col-lg-11{flex:0 0 91.666667%;max-width:91.666667%}.col-lg-12{flex:0 0 100%;max-width:100%}.order-lg-first{order:-1}.order-lg-last{order:13}.order-lg-0{order:0}.order-lg-1{order:1}.order-lg-2{order:2}.order-lg-3{order:3}.order-lg-4{order:4}.order-lg-5{order:5}.order-lg-6{order:6}.order-lg-7{order:7}.order-lg-8{order:8}.order-lg-9{order:9}.order-lg-10{order:10}.order-lg-11{order:11}.order-lg-12{order:12}.offset-lg-0{margin-left:0}.offset-lg-1{margin-left:8.333333%}.offset-lg-2{margin-left:16.666667%}.offset-lg-3{margin-left:25%}.offset-lg-4{margin-left:33.333333%}.offset-lg-5{margin-left:41.666667%}.offset-lg-6{margin-left:50%}.offset-lg-7{margin-left:58.333333%}.offset-lg-8{margin-left:66.666667%}.offset-lg-9{margin-left:75%}.offset-lg-10{margin-left:83.333333%}.offset-lg-11{margin-left:91.666667%}}@media (min-width:1200px){.col-xl{flex-basis:0;flex-grow:1;max-width:100%}.row-cols-xl-1>*{flex:0 0 100%;max-width:100%}.row-cols-xl-2>*{flex:0 0 50%;max-width:50%}.row-cols-xl-3>*{flex:0 0 33.333333%;max-width:33.333333%}.row-cols-xl-4>*{flex:0 0 25%;max-width:25%}.row-cols-xl-5>*{flex:0 0 20%;max-width:20%}.row-cols-xl-6>*{flex:0 0 16.666667%;max-width:16.666667%}.col-xl-auto{flex:0 0 auto;width:auto;max-width:100%}.col-xl-1{flex:0 0 8.333333%;max-width:8.333333%}.col-xl-2{flex:0 0 16.666667%;max-width:16.666667%}.col-xl-3{flex:0 0 25%;max-width:25%}.col-xl-4{flex:0 0 33.333333%;max-width:33.333333%}.col-xl-5{flex:0 0 41.666667%;max-width:41.666667%}.col-xl-6{flex:0 0 50%;max-width:50%}.col-xl-7{flex:0 0 58.333333%;max-width:58.333333%}.col-xl-8{flex:0 0 66.666667%;max-width:66.666667%}.col-xl-9{flex:0 0 75%;max-width:75%}.col-xl-10{flex:0 0 83.333333%;max-width:83.333333%}.col-xl-11{flex:0 0 91.666667%;max-width:91.666667%}.col-xl-12{flex:0 0 100%;max-width:100%}.order-xl-first{order:-1}.order-xl-last{order:13}.order-xl-0{order:0}.order-xl-1{order:1}.order-xl-2{order:2}.order-xl-3{order:3}.order-xl-4{order:4}.order-xl-5{order:5}.order-xl-6{order:6}.order-xl-7{order:7}.order-xl-8{order:8}.order-xl-9{order:9}.order-xl-10{order:10}.order-xl-11{order:11}.order-xl-12{order:12}.offset-xl-0{margin-left:0}.offset-xl-1{margin-left:8.333333%}.offset-xl-2{margin-left:16.666667%}.offset-xl-3{margin-left:25%}.offset-xl-4{margin-left:33.333333%}.offset-xl-5{margin-left:41.666667%}.offset-xl-6{margin-left:50%}.offset-xl-7{margin-left:58.333333%}.offset-xl-8{margin-left:66.666667%}.offset-xl-9{margin-left:75%}.offset-xl-10{margin-left:83.333333%}.offset-xl-11{margin-left:91.666667%}}.table{width:100%;margin-bottom:1rem;color:#212529;background-color:transparent}.table td,.table th{padding:.75rem;vertical-align:top;border-top:1px solid #dee2e6}.table thead th{vertical-align:bottom;border-bottom:2px solid #dee2e6}.table tbody+tbody{border-top:2px solid #dee2e6}.table-sm td,.table-sm th{padding:.3rem}.table-bordered,.table-bordered td,.table-bordered th{border:1px solid #dee2e6}.table-bordered thead td,.table-bordered thead th{border-bottom-width:2px}.table-borderless tbody+tbody,.table-borderless td,.table-borderless th,.table-borderless thead th{border:0}.table-striped tbody tr:nth-of-type(odd){background-color:rgba(0,0,0,.05)}.table-hover tbody tr:hover{color:#212529;background-color:rgba(0,0,0,.075)}.table-primary,.table-primary>td,.table-primary>th{background-color:#b8daff}.table-primary tbody+tbody,.table-primary td,.table-primary th,.table-primary thead th{border-color:#7abaff}.table-hover .table-primary:hover,.table-hover .table-primary:hover>td,.table-hover .table-primary:hover>th{background-color:#9fcdff}.table-secondary,.table-secondary>td,.table-secondary>th{background-color:#d6d8db}.table-secondary tbody+tbody,.table-secondary td,.table-secondary th,.table-secondary thead th{border-color:#b3b7bb}.table-hover .table-secondary:hover,.table-hover .table-secondary:hover>td,.table-hover .table-secondary:hover>th{background-color:#c8cbcf}.table-success,.table-success>td,.table-success>th{background-color:#c3e6cb}.table-success tbody+tbody,.table-success td,.table-success th,.table-success thead th{border-color:#8fd19e}.table-hover .table-success:hover,.table-hover .table-success:hover>td,.table-hover .table-success:hover>th{background-color:#b1dfbb}.table-info,.table-info>td,.table-info>th{background-color:#bee5eb}.table-info tbody+tbody,.table-info td,.table-info th,.table-info thead th{border-color:#86cfda}.table-hover .table-info:hover,.table-hover .table-info:hover>td,.table-hover .table-info:hover>th{background-color:#abdde5}.table-warning,.table-warning>td,.table-warning>th{background-color:#ffeeba}.table-warning tbody+tbody,.table-warning td,.table-warning th,.table-warning thead th{border-color:#ffdf7e}.table-hover .table-warning:hover,.table-hover .table-warning:hover>td,.table-hover .table-warning:hover>th{background-color:#ffe8a1}.table-danger,.table-danger>td,.table-danger>th{background-color:#f5c6cb}.table-danger tbody+tbody,.table-danger td,.table-danger th,.table-danger thead th{border-color:#ed969e}.table-hover .table-danger:hover,.table-hover .table-danger:hover>td,.table-hover .table-danger:hover>th{background-color:#f1b0b7}.table-light,.table-light>td,.table-light>th{background-color:#fdfdfe}.table-light tbody+tbody,.table-light td,.table-light th,.table-light thead th{border-color:#fbfcfc}.table-hover .table-light:hover,.table-hover .table-light:hover>td,.table-hover .table-light:hover>th{background-color:#ececf6}.table-dark,.table-dark>td,.table-dark>th{background-color:#c6c8ca}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#95999c}.table-hover .table-dark:hover,.table-hover .table-dark:hover>td,.table-hover .table-dark:hover>th{background-color:#b9bbbe}.table-active,.table-active>td,.table-active>th,.table-hover .table-active:hover,.table-hover .table-active:hover>td,.table-hover .table-active:hover>th{background-color:rgba(0,0,0,.075)}.table .thead-dark th{color:#fff;background-color:#212529;border-color:#383f45}.table .thead-light th{color:#495057;background-color:#e9ecef;border-color:#dee2e6}.table-dark{color:#fff;background-color:#212529}.table-dark td,.table-dark th,.table-dark thead th{border-color:#383f45}.table-dark.table-bordered{border:0}.table-dark.table-striped tbody tr:nth-of-type(odd){background-color:hsla(0,0%,100%,.05)}.table-dark.table-hover tbody tr:hover{color:#fff;background-color:hsla(0,0%,100%,.075)}@media (max-width:575.98px){.table-responsive-sm{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-sm>.table-bordered{border:0}}@media (max-width:767.98px){.table-responsive-md{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-md>.table-bordered{border:0}}@media (max-width:991.98px){.table-responsive-lg{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-lg>.table-bordered{border:0}}@media (max-width:1199.98px){.table-responsive-xl{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive-xl>.table-bordered{border:0}}.table-responsive{display:block;width:100%;overflow-x:auto;-webkit-overflow-scrolling:touch}.table-responsive>.table-bordered{border:0}.form-control{display:block;width:100%;height:calc(2.25rem + 2px);padding:.375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;background-color:#fff;background-clip:padding-box;border:1px solid #ced4da;border-radius:.25rem;box-shadow:inset 0 0 0 transparent;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.form-control{transition:none}}.form-control::-ms-expand{background-color:transparent;border:0}.form-control:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.form-control:focus{color:#495057;background-color:#fff;border-color:#80bdff;outline:0;box-shadow:inset 0 0 0 transparent,none}.form-control::-moz-placeholder{color:#939ba2;opacity:1}.form-control:-ms-input-placeholder{color:#939ba2;opacity:1}.form-control::-ms-input-placeholder{color:#939ba2;opacity:1}.form-control::placeholder{color:#939ba2;opacity:1}.form-control:disabled,.form-control[readonly]{background-color:#e9ecef;opacity:1}select.form-control:focus::-ms-value{color:#495057;background-color:#fff}.form-control-file,.form-control-range{display:block;width:100%}.col-form-label{padding-top:calc(.375rem + 1px);padding-bottom:calc(.375rem + 1px);margin-bottom:0;font-size:inherit;line-height:1.5}.col-form-label-lg{padding-top:calc(.5rem + 1px);padding-bottom:calc(.5rem + 1px);font-size:1.25rem;line-height:1.5}.col-form-label-sm{padding-top:calc(.25rem + 1px);padding-bottom:calc(.25rem + 1px);font-size:.875rem;line-height:1.5}.form-control-plaintext{display:block;width:100%;padding:.375rem 0;margin-bottom:0;font-size:1rem;line-height:1.5;color:#212529;background-color:transparent;border:solid transparent;border-width:1px 0}.form-control-plaintext.form-control-lg,.form-control-plaintext.form-control-sm{padding-right:0;padding-left:0}.form-control-sm{height:calc(1.8125rem + 2px);padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.form-control-lg{height:calc(2.875rem + 2px);padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}select.form-control[multiple],select.form-control[size],textarea.form-control{height:auto}.form-group{margin-bottom:1rem}.form-text{display:block;margin-top:.25rem}.form-row{display:flex;flex-wrap:wrap;margin-right:-5px;margin-left:-5px}.form-row>.col,.form-row>[class*=col-]{padding-right:5px;padding-left:5px}.form-check{position:relative;display:block;padding-left:1.25rem}.form-check-input{position:absolute;margin-top:.3rem;margin-left:-1.25rem}.form-check-input:disabled~.form-check-label,.form-check-input[disabled]~.form-check-label{color:#6c757d}.form-check-label{margin-bottom:0}.form-check-inline{display:inline-flex;align-items:center;padding-left:0;margin-right:.75rem}.form-check-inline .form-check-input{position:static;margin-top:0;margin-right:.3125rem;margin-left:0}.valid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#28a745}.valid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(40,167,69,.9);border-radius:.25rem}.is-valid~.valid-feedback,.is-valid~.valid-tooltip,.was-validated :valid~.valid-feedback,.was-validated :valid~.valid-tooltip{display:block}.form-control.is-valid,.was-validated .form-control:valid{border-color:#28a745;padding-right:2.25rem;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-valid:focus,.was-validated .form-control:valid:focus{border-color:#28a745;box-shadow:0 0 0 0 rgba(40,167,69,.25)}.was-validated textarea.form-control:valid,textarea.form-control.is-valid{padding-right:2.25rem;background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-valid,.was-validated .custom-select:valid{border-color:#28a745;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='8' height='8'%3E%3Cpath fill='%2328a745' d='M2.3 6.73L.6 4.53c-.4-1.04.46-1.4 1.1-.8l1.1 1.4 3.4-3.8c.6-.63 1.6-.27 1.2.7l-4 4.6c-.43.5-.8.4-1.1.1z'/%3E%3C/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-valid:focus,.was-validated .custom-select:valid:focus{border-color:#28a745;box-shadow:0 0 0 0 rgba(40,167,69,.25)}.form-check-input.is-valid~.form-check-label,.was-validated .form-check-input:valid~.form-check-label{color:#28a745}.form-check-input.is-valid~.valid-feedback,.form-check-input.is-valid~.valid-tooltip,.was-validated .form-check-input:valid~.valid-feedback,.was-validated .form-check-input:valid~.valid-tooltip{display:block}.custom-control-input.is-valid~.custom-control-label,.was-validated .custom-control-input:valid~.custom-control-label{color:#28a745}.custom-control-input.is-valid~.custom-control-label:before,.was-validated .custom-control-input:valid~.custom-control-label:before{border-color:#28a745}.custom-control-input.is-valid:checked~.custom-control-label:before,.was-validated .custom-control-input:valid:checked~.custom-control-label:before{border-color:#34ce57;background-color:#34ce57}.custom-control-input.is-valid:focus~.custom-control-label:before,.was-validated .custom-control-input:valid:focus~.custom-control-label:before{box-shadow:0 0 0 0 rgba(40,167,69,.25)}.custom-control-input.is-valid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-valid~.custom-file-label,.was-validated .custom-control-input:valid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:valid~.custom-file-label{border-color:#28a745}.custom-file-input.is-valid:focus~.custom-file-label,.was-validated .custom-file-input:valid:focus~.custom-file-label{border-color:#28a745;box-shadow:0 0 0 0 rgba(40,167,69,.25)}.invalid-feedback{display:none;width:100%;margin-top:.25rem;font-size:80%;color:#dc3545}.invalid-tooltip{position:absolute;top:100%;z-index:5;display:none;max-width:100%;padding:.25rem .5rem;margin-top:.1rem;font-size:.875rem;line-height:1.5;color:#fff;background-color:rgba(220,53,69,.9);border-radius:.25rem}.is-invalid~.invalid-feedback,.is-invalid~.invalid-tooltip,.was-validated :invalid~.invalid-feedback,.was-validated :invalid~.invalid-tooltip{display:block}.form-control.is-invalid,.was-validated .form-control:invalid{border-color:#dc3545;padding-right:2.25rem;background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right calc(.375em + .1875rem) center;background-size:calc(.75em + .375rem) calc(.75em + .375rem)}.form-control.is-invalid:focus,.was-validated .form-control:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 0 rgba(220,53,69,.25)}.was-validated textarea.form-control:invalid,textarea.form-control.is-invalid{padding-right:2.25rem;background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-invalid,.was-validated .custom-select:invalid{border-color:#dc3545;padding-right:calc(.75em + 2.3125rem);background:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px,url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23dc3545'%3E%3Ccircle cx='6' cy='6' r='4.5'/%3E%3Cpath stroke-linejoin='round' d='M5.8 3.6h.4L6 6.5z'/%3E%3Ccircle cx='6' cy='8.2' r='.6' fill='%23dc3545' stroke='none'/%3E%3C/svg%3E") #fff no-repeat center right 1.75rem/calc(.75em + .375rem) calc(.75em + .375rem)}.custom-select.is-invalid:focus,.was-validated .custom-select:invalid:focus{border-color:#dc3545;box-shadow:0 0 0 0 rgba(220,53,69,.25)}.form-check-input.is-invalid~.form-check-label,.was-validated .form-check-input:invalid~.form-check-label{color:#dc3545}.form-check-input.is-invalid~.invalid-feedback,.form-check-input.is-invalid~.invalid-tooltip,.was-validated .form-check-input:invalid~.invalid-feedback,.was-validated .form-check-input:invalid~.invalid-tooltip{display:block}.custom-control-input.is-invalid~.custom-control-label,.was-validated .custom-control-input:invalid~.custom-control-label{color:#dc3545}.custom-control-input.is-invalid~.custom-control-label:before,.was-validated .custom-control-input:invalid~.custom-control-label:before{border-color:#dc3545}.custom-control-input.is-invalid:checked~.custom-control-label:before,.was-validated .custom-control-input:invalid:checked~.custom-control-label:before{border-color:#e4606d;background-color:#e4606d}.custom-control-input.is-invalid:focus~.custom-control-label:before,.was-validated .custom-control-input:invalid:focus~.custom-control-label:before{box-shadow:0 0 0 0 rgba(220,53,69,.25)}.custom-control-input.is-invalid:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-invalid~.custom-file-label,.was-validated .custom-control-input:invalid:focus:not(:checked)~.custom-control-label:before,.was-validated .custom-file-input:invalid~.custom-file-label{border-color:#dc3545}.custom-file-input.is-invalid:focus~.custom-file-label,.was-validated .custom-file-input:invalid:focus~.custom-file-label{border-color:#dc3545;box-shadow:0 0 0 0 rgba(220,53,69,.25)}.form-inline{display:flex;flex-flow:row wrap;align-items:center}.form-inline .form-check{width:100%}@media (min-width:576px){.form-inline label{justify-content:center}.form-inline .form-group,.form-inline label{display:flex;align-items:center;margin-bottom:0}.form-inline .form-group{flex:0 0 auto;flex-flow:row wrap}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-plaintext{display:inline-block}.form-inline .custom-select,.form-inline .input-group{width:auto}.form-inline .form-check{display:flex;align-items:center;justify-content:center;width:auto;padding-left:0}.form-inline .form-check-input{position:relative;flex-shrink:0;margin-top:0;margin-right:.25rem;margin-left:0}.form-inline .custom-control{align-items:center;justify-content:center}.form-inline .custom-control-label{margin-bottom:0}}.btn{display:inline-block;font-weight:400;color:#212529;text-align:center;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;background-color:transparent;border:1px solid transparent;padding:.375rem .75rem;font-size:1rem;line-height:1.5;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.btn{transition:none}}.btn:hover{color:#212529;text-decoration:none}.btn.focus,.btn:focus{outline:0;box-shadow:none}.btn.disabled,.btn:disabled{opacity:.65;box-shadow:none}.btn:not(:disabled):not(.disabled).active,.btn:not(:disabled):not(.disabled):active{box-shadow:none}a.btn.disabled,fieldset:disabled a.btn{pointer-events:none}.btn-primary{color:#fff;background-color:#007bff;border-color:#007bff;box-shadow:none}.btn-primary.focus,.btn-primary:focus,.btn-primary:hover{color:#fff;background-color:#0069d9;border-color:#0062cc}.btn-primary.focus,.btn-primary:focus{box-shadow:none,0 0 0 0 rgba(38,143,255,.5)}.btn-primary.disabled,.btn-primary:disabled{color:#fff;background-color:#007bff;border-color:#007bff}.btn-primary:not(:disabled):not(.disabled).active,.btn-primary:not(:disabled):not(.disabled):active,.show>.btn-primary.dropdown-toggle{color:#fff;background-color:#0062cc;border-color:#005cbf}.btn-primary:not(:disabled):not(.disabled).active:focus,.btn-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(38,143,255,.5)}.btn-secondary{color:#fff;background-color:#6c757d;border-color:#6c757d;box-shadow:none}.btn-secondary.focus,.btn-secondary:focus,.btn-secondary:hover{color:#fff;background-color:#5a6268;border-color:#545b62}.btn-secondary.focus,.btn-secondary:focus{box-shadow:none,0 0 0 0 rgba(130,138,145,.5)}.btn-secondary.disabled,.btn-secondary:disabled{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-secondary:not(:disabled):not(.disabled).active,.btn-secondary:not(:disabled):not(.disabled):active,.show>.btn-secondary.dropdown-toggle{color:#fff;background-color:#545b62;border-color:#4e555b}.btn-secondary:not(:disabled):not(.disabled).active:focus,.btn-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(130,138,145,.5)}.btn-success{color:#fff;background-color:#28a745;border-color:#28a745;box-shadow:none}.btn-success.focus,.btn-success:focus,.btn-success:hover{color:#fff;background-color:#218838;border-color:#1e7e34}.btn-success.focus,.btn-success:focus{box-shadow:none,0 0 0 0 rgba(72,180,97,.5)}.btn-success.disabled,.btn-success:disabled{color:#fff;background-color:#28a745;border-color:#28a745}.btn-success:not(:disabled):not(.disabled).active,.btn-success:not(:disabled):not(.disabled):active,.show>.btn-success.dropdown-toggle{color:#fff;background-color:#1e7e34;border-color:#1c7430}.btn-success:not(:disabled):not(.disabled).active:focus,.btn-success:not(:disabled):not(.disabled):active:focus,.show>.btn-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(72,180,97,.5)}.btn-info{color:#fff;background-color:#17a2b8;border-color:#17a2b8;box-shadow:none}.btn-info.focus,.btn-info:focus,.btn-info:hover{color:#fff;background-color:#138496;border-color:#117a8b}.btn-info.focus,.btn-info:focus{box-shadow:none,0 0 0 0 rgba(58,176,195,.5)}.btn-info.disabled,.btn-info:disabled{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-info:not(:disabled):not(.disabled).active,.btn-info:not(:disabled):not(.disabled):active,.show>.btn-info.dropdown-toggle{color:#fff;background-color:#117a8b;border-color:#10707f}.btn-info:not(:disabled):not(.disabled).active:focus,.btn-info:not(:disabled):not(.disabled):active:focus,.show>.btn-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(58,176,195,.5)}.btn-warning{color:#1f2d3d;background-color:#ffc107;border-color:#ffc107;box-shadow:none}.btn-warning.focus,.btn-warning:focus,.btn-warning:hover{color:#1f2d3d;background-color:#e0a800;border-color:#d39e00}.btn-warning.focus,.btn-warning:focus{box-shadow:none,0 0 0 0 rgba(221,171,15,.5)}.btn-warning.disabled,.btn-warning:disabled{color:#1f2d3d;background-color:#ffc107;border-color:#ffc107}.btn-warning:not(:disabled):not(.disabled).active,.btn-warning:not(:disabled):not(.disabled):active,.show>.btn-warning.dropdown-toggle{color:#1f2d3d;background-color:#d39e00;border-color:#c69500}.btn-warning:not(:disabled):not(.disabled).active:focus,.btn-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(221,171,15,.5)}.btn-danger{color:#fff;background-color:#dc3545;border-color:#dc3545;box-shadow:none}.btn-danger.focus,.btn-danger:focus,.btn-danger:hover{color:#fff;background-color:#c82333;border-color:#bd2130}.btn-danger.focus,.btn-danger:focus{box-shadow:none,0 0 0 0 rgba(225,83,97,.5)}.btn-danger.disabled,.btn-danger:disabled{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-danger:not(:disabled):not(.disabled).active,.btn-danger:not(:disabled):not(.disabled):active,.show>.btn-danger.dropdown-toggle{color:#fff;background-color:#bd2130;border-color:#b21f2d}.btn-danger:not(:disabled):not(.disabled).active:focus,.btn-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(225,83,97,.5)}.btn-light{color:#1f2d3d;background-color:#f8f9fa;border-color:#f8f9fa;box-shadow:none}.btn-light.focus,.btn-light:focus,.btn-light:hover{color:#1f2d3d;background-color:#e2e6ea;border-color:#dae0e5}.btn-light.focus,.btn-light:focus{box-shadow:none,0 0 0 0 rgba(215,218,222,.5)}.btn-light.disabled,.btn-light:disabled{color:#1f2d3d;background-color:#f8f9fa;border-color:#f8f9fa}.btn-light:not(:disabled):not(.disabled).active,.btn-light:not(:disabled):not(.disabled):active,.show>.btn-light.dropdown-toggle{color:#1f2d3d;background-color:#dae0e5;border-color:#d3d9df}.btn-light:not(:disabled):not(.disabled).active:focus,.btn-light:not(:disabled):not(.disabled):active:focus,.show>.btn-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(215,218,222,.5)}.btn-dark{color:#fff;background-color:#343a40;border-color:#343a40;box-shadow:none}.btn-dark.focus,.btn-dark:focus,.btn-dark:hover{color:#fff;background-color:#23272b;border-color:#1d2124}.btn-dark.focus,.btn-dark:focus{box-shadow:none,0 0 0 0 rgba(82,88,93,.5)}.btn-dark.disabled,.btn-dark:disabled{color:#fff;background-color:#343a40;border-color:#343a40}.btn-dark:not(:disabled):not(.disabled).active,.btn-dark:not(:disabled):not(.disabled):active,.show>.btn-dark.dropdown-toggle{color:#fff;background-color:#1d2124;border-color:#171a1d}.btn-dark:not(:disabled):not(.disabled).active:focus,.btn-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(82,88,93,.5)}.btn-outline-primary{color:#007bff;border-color:#007bff}.btn-outline-primary:hover{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary.focus,.btn-outline-primary:focus{box-shadow:0 0 0 0 rgba(0,123,255,.5)}.btn-outline-primary.disabled,.btn-outline-primary:disabled{color:#007bff;background-color:transparent}.btn-outline-primary:not(:disabled):not(.disabled).active,.btn-outline-primary:not(:disabled):not(.disabled):active,.show>.btn-outline-primary.dropdown-toggle{color:#fff;background-color:#007bff;border-color:#007bff}.btn-outline-primary:not(:disabled):not(.disabled).active:focus,.btn-outline-primary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-primary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(0,123,255,.5)}.btn-outline-secondary{color:#6c757d;border-color:#6c757d}.btn-outline-secondary:hover{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary.focus,.btn-outline-secondary:focus{box-shadow:0 0 0 0 rgba(108,117,125,.5)}.btn-outline-secondary.disabled,.btn-outline-secondary:disabled{color:#6c757d;background-color:transparent}.btn-outline-secondary:not(:disabled):not(.disabled).active,.btn-outline-secondary:not(:disabled):not(.disabled):active,.show>.btn-outline-secondary.dropdown-toggle{color:#fff;background-color:#6c757d;border-color:#6c757d}.btn-outline-secondary:not(:disabled):not(.disabled).active:focus,.btn-outline-secondary:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-secondary.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(108,117,125,.5)}.btn-outline-success{color:#28a745;border-color:#28a745}.btn-outline-success:hover{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success.focus,.btn-outline-success:focus{box-shadow:0 0 0 0 rgba(40,167,69,.5)}.btn-outline-success.disabled,.btn-outline-success:disabled{color:#28a745;background-color:transparent}.btn-outline-success:not(:disabled):not(.disabled).active,.btn-outline-success:not(:disabled):not(.disabled):active,.show>.btn-outline-success.dropdown-toggle{color:#fff;background-color:#28a745;border-color:#28a745}.btn-outline-success:not(:disabled):not(.disabled).active:focus,.btn-outline-success:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-success.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(40,167,69,.5)}.btn-outline-info{color:#17a2b8;border-color:#17a2b8}.btn-outline-info:hover{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info.focus,.btn-outline-info:focus{box-shadow:0 0 0 0 rgba(23,162,184,.5)}.btn-outline-info.disabled,.btn-outline-info:disabled{color:#17a2b8;background-color:transparent}.btn-outline-info:not(:disabled):not(.disabled).active,.btn-outline-info:not(:disabled):not(.disabled):active,.show>.btn-outline-info.dropdown-toggle{color:#fff;background-color:#17a2b8;border-color:#17a2b8}.btn-outline-info:not(:disabled):not(.disabled).active:focus,.btn-outline-info:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-info.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(23,162,184,.5)}.btn-outline-warning{color:#ffc107;border-color:#ffc107}.btn-outline-warning:hover{color:#1f2d3d;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning.focus,.btn-outline-warning:focus{box-shadow:0 0 0 0 rgba(255,193,7,.5)}.btn-outline-warning.disabled,.btn-outline-warning:disabled{color:#ffc107;background-color:transparent}.btn-outline-warning:not(:disabled):not(.disabled).active,.btn-outline-warning:not(:disabled):not(.disabled):active,.show>.btn-outline-warning.dropdown-toggle{color:#1f2d3d;background-color:#ffc107;border-color:#ffc107}.btn-outline-warning:not(:disabled):not(.disabled).active:focus,.btn-outline-warning:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-warning.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(255,193,7,.5)}.btn-outline-danger{color:#dc3545;border-color:#dc3545}.btn-outline-danger:hover{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger.focus,.btn-outline-danger:focus{box-shadow:0 0 0 0 rgba(220,53,69,.5)}.btn-outline-danger.disabled,.btn-outline-danger:disabled{color:#dc3545;background-color:transparent}.btn-outline-danger:not(:disabled):not(.disabled).active,.btn-outline-danger:not(:disabled):not(.disabled):active,.show>.btn-outline-danger.dropdown-toggle{color:#fff;background-color:#dc3545;border-color:#dc3545}.btn-outline-danger:not(:disabled):not(.disabled).active:focus,.btn-outline-danger:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-danger.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(220,53,69,.5)}.btn-outline-light{color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:hover{color:#1f2d3d;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light.focus,.btn-outline-light:focus{box-shadow:0 0 0 0 rgba(248,249,250,.5)}.btn-outline-light.disabled,.btn-outline-light:disabled{color:#f8f9fa;background-color:transparent}.btn-outline-light:not(:disabled):not(.disabled).active,.btn-outline-light:not(:disabled):not(.disabled):active,.show>.btn-outline-light.dropdown-toggle{color:#1f2d3d;background-color:#f8f9fa;border-color:#f8f9fa}.btn-outline-light:not(:disabled):not(.disabled).active:focus,.btn-outline-light:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-light.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(248,249,250,.5)}.btn-outline-dark{color:#343a40;border-color:#343a40}.btn-outline-dark:hover{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark.focus,.btn-outline-dark:focus{box-shadow:0 0 0 0 rgba(52,58,64,.5)}.btn-outline-dark.disabled,.btn-outline-dark:disabled{color:#343a40;background-color:transparent}.btn-outline-dark:not(:disabled):not(.disabled).active,.btn-outline-dark:not(:disabled):not(.disabled):active,.show>.btn-outline-dark.dropdown-toggle{color:#fff;background-color:#343a40;border-color:#343a40}.btn-outline-dark:not(:disabled):not(.disabled).active:focus,.btn-outline-dark:not(:disabled):not(.disabled):active:focus,.show>.btn-outline-dark.dropdown-toggle:focus{box-shadow:0 0 0 0 rgba(52,58,64,.5)}.btn-link{font-weight:400;color:#007bff;text-decoration:none}.btn-link:hover{color:#0056b3;text-decoration:none}.btn-link.focus,.btn-link:focus{text-decoration:none;box-shadow:none}.btn-link.disabled,.btn-link:disabled{color:#6c757d;pointer-events:none}.btn-group-lg>.btn,.btn-lg{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.btn-group-sm>.btn,.btn-sm{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:.5rem}input[type=button].btn-block,input[type=reset].btn-block,input[type=submit].btn-block{width:100%}.fade{transition:opacity .15s linear}@media (prefers-reduced-motion:reduce){.fade{transition:none}}.fade:not(.show){opacity:0}.collapse:not(.show){display:none}.collapsing{position:relative;height:0;overflow:hidden;transition:height .35s ease}@media (prefers-reduced-motion:reduce){.collapsing{transition:none}}.dropdown,.dropleft,.dropright,.dropup{position:relative}.dropdown-toggle{white-space:nowrap}.dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid;border-right:.3em solid transparent;border-bottom:0;border-left:.3em solid transparent}.dropdown-toggle:empty:after{margin-left:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:10rem;padding:.5rem 0;margin:.125rem 0 0;font-size:1rem;color:#212529;text-align:left;list-style:none;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.15);border-radius:.25rem;box-shadow:0 .5rem 1rem rgba(0,0,0,.175)}.dropdown-menu-left{right:auto;left:0}.dropdown-menu-right{right:0;left:auto}@media (min-width:576px){.dropdown-menu-sm-left{right:auto;left:0}.dropdown-menu-sm-right{right:0;left:auto}}@media (min-width:768px){.dropdown-menu-md-left{right:auto;left:0}.dropdown-menu-md-right{right:0;left:auto}}@media (min-width:992px){.dropdown-menu-lg-left{right:auto;left:0}.dropdown-menu-lg-right{right:0;left:auto}}@media (min-width:1200px){.dropdown-menu-xl-left{right:auto;left:0}.dropdown-menu-xl-right{right:0;left:auto}}.dropup .dropdown-menu{top:auto;bottom:100%;margin-top:0;margin-bottom:.125rem}.dropup .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:0;border-right:.3em solid transparent;border-bottom:.3em solid;border-left:.3em solid transparent}.dropup .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-menu{top:0;right:auto;left:100%;margin-top:0;margin-left:.125rem}.dropright .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid}.dropright .dropdown-toggle:empty:after{margin-left:0}.dropright .dropdown-toggle:after{vertical-align:0}.dropleft .dropdown-menu{top:0;right:100%;left:auto;margin-top:0;margin-right:.125rem}.dropleft .dropdown-toggle:after{display:inline-block;margin-left:.255em;vertical-align:.255em;content:"";display:none}.dropleft .dropdown-toggle:before{display:inline-block;margin-right:.255em;vertical-align:.255em;content:"";border-top:.3em solid transparent;border-right:.3em solid;border-bottom:.3em solid transparent}.dropleft .dropdown-toggle:empty:after{margin-left:0}.dropleft .dropdown-toggle:before{vertical-align:0}.dropdown-menu[x-placement^=bottom],.dropdown-menu[x-placement^=left],.dropdown-menu[x-placement^=right],.dropdown-menu[x-placement^=top]{right:auto;bottom:auto}.dropdown-divider{height:0;margin:.5rem 0;overflow:hidden;border-top:1px solid #e9ecef}.dropdown-item{display:block;width:100%;padding:.25rem 1rem;clear:both;font-weight:400;color:#212529;text-align:inherit;white-space:nowrap;background-color:transparent;border:0}.dropdown-item:focus,.dropdown-item:hover{color:#16181b;text-decoration:none;background-color:#f8f9fa}.dropdown-item.active,.dropdown-item:active{color:#fff;text-decoration:none;background-color:#007bff}.dropdown-item.disabled,.dropdown-item:disabled{color:#6c757d;pointer-events:none;background-color:transparent}.dropdown-menu.show{display:block}.dropdown-header{display:block;padding:.5rem 1rem;margin-bottom:0;font-size:.875rem;color:#6c757d;white-space:nowrap}.dropdown-item-text{display:block;padding:.25rem 1rem;color:#212529}.btn-group,.btn-group-vertical{position:relative;display:inline-flex;vertical-align:middle}.btn-group-vertical>.btn,.btn-group>.btn{position:relative;flex:1 1 auto}.btn-group-vertical>.btn.active,.btn-group-vertical>.btn:active,.btn-group-vertical>.btn:focus,.btn-group-vertical>.btn:hover,.btn-group>.btn.active,.btn-group>.btn:active,.btn-group>.btn:focus,.btn-group>.btn:hover{z-index:1}.btn-toolbar{display:flex;flex-wrap:wrap;justify-content:flex-start}.btn-toolbar .input-group{width:auto}.btn-group>.btn-group:not(:first-child),.btn-group>.btn:not(:first-child){margin-left:-1px}.btn-group>.btn-group:not(:last-child)>.btn,.btn-group>.btn:not(:last-child):not(.dropdown-toggle){border-top-right-radius:0;border-bottom-right-radius:0}.btn-group>.btn-group:not(:first-child)>.btn,.btn-group>.btn:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.dropdown-toggle-split{padding-right:.5625rem;padding-left:.5625rem}.dropdown-toggle-split:after,.dropright .dropdown-toggle-split:after,.dropup .dropdown-toggle-split:after{margin-left:0}.dropleft .dropdown-toggle-split:before{margin-right:0}.btn-group-sm>.btn+.dropdown-toggle-split,.btn-sm+.dropdown-toggle-split{padding-right:.375rem;padding-left:.375rem}.btn-group-lg>.btn+.dropdown-toggle-split,.btn-lg+.dropdown-toggle-split{padding-right:.75rem;padding-left:.75rem}.btn-group.show .dropdown-toggle,.btn-group.show .dropdown-toggle.btn-link{box-shadow:none}.btn-group-vertical{flex-direction:column;align-items:flex-start;justify-content:center}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group{width:100%}.btn-group-vertical>.btn-group:not(:first-child),.btn-group-vertical>.btn:not(:first-child){margin-top:-1px}.btn-group-vertical>.btn-group:not(:last-child)>.btn,.btn-group-vertical>.btn:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child)>.btn,.btn-group-vertical>.btn:not(:first-child){border-top-left-radius:0;border-top-right-radius:0}.btn-group-toggle>.btn,.btn-group-toggle>.btn-group>.btn{margin-bottom:0}.btn-group-toggle>.btn-group>.btn input[type=checkbox],.btn-group-toggle>.btn-group>.btn input[type=radio],.btn-group-toggle>.btn input[type=checkbox],.btn-group-toggle>.btn input[type=radio]{position:absolute;clip:rect(0,0,0,0);pointer-events:none}.input-group{position:relative;display:flex;flex-wrap:wrap;align-items:stretch;width:100%}.input-group>.custom-file,.input-group>.custom-select,.input-group>.form-control,.input-group>.form-control-plaintext{position:relative;flex:1 1 0%;min-width:0;margin-bottom:0}.input-group>.custom-file+.custom-file,.input-group>.custom-file+.custom-select,.input-group>.custom-file+.form-control,.input-group>.custom-select+.custom-file,.input-group>.custom-select+.custom-select,.input-group>.custom-select+.form-control,.input-group>.form-control+.custom-file,.input-group>.form-control+.custom-select,.input-group>.form-control+.form-control,.input-group>.form-control-plaintext+.custom-file,.input-group>.form-control-plaintext+.custom-select,.input-group>.form-control-plaintext+.form-control{margin-left:-1px}.input-group>.custom-file .custom-file-input:focus~.custom-file-label,.input-group>.custom-select:focus,.input-group>.form-control:focus{z-index:3}.input-group>.custom-file .custom-file-input:focus{z-index:4}.input-group>.custom-select:not(:last-child),.input-group>.form-control:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-select:not(:first-child),.input-group>.form-control:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.input-group>.custom-file{display:flex;align-items:center}.input-group>.custom-file:not(:last-child) .custom-file-label,.input-group>.custom-file:not(:last-child) .custom-file-label:after{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.custom-file:not(:first-child) .custom-file-label{border-top-left-radius:0;border-bottom-left-radius:0}.input-group-append,.input-group-prepend{display:flex}.input-group-append .btn,.input-group-prepend .btn{position:relative;z-index:2}.input-group-append .btn:focus,.input-group-prepend .btn:focus{z-index:3}.input-group-append .btn+.btn,.input-group-append .btn+.input-group-text,.input-group-append .input-group-text+.btn,.input-group-append .input-group-text+.input-group-text,.input-group-prepend .btn+.btn,.input-group-prepend .btn+.input-group-text,.input-group-prepend .input-group-text+.btn,.input-group-prepend .input-group-text+.input-group-text{margin-left:-1px}.input-group-prepend{margin-right:-1px}.input-group-append{margin-left:-1px}.input-group-text{display:flex;align-items:center;padding:.375rem .75rem;margin-bottom:0;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;text-align:center;white-space:nowrap;background-color:#e9ecef;border:1px solid #ced4da;border-radius:.25rem}.input-group-text input[type=checkbox],.input-group-text input[type=radio]{margin-top:0}.input-group-lg>.custom-select,.input-group-lg>.form-control:not(textarea){height:calc(2.875rem + 2px)}.input-group-lg>.custom-select,.input-group-lg>.form-control,.input-group-lg>.input-group-append>.btn,.input-group-lg>.input-group-append>.input-group-text,.input-group-lg>.input-group-prepend>.btn,.input-group-lg>.input-group-prepend>.input-group-text{padding:.5rem 1rem;font-size:1.25rem;line-height:1.5;border-radius:.3rem}.input-group-sm>.custom-select,.input-group-sm>.form-control:not(textarea){height:calc(1.8125rem + 2px)}.input-group-sm>.custom-select,.input-group-sm>.form-control,.input-group-sm>.input-group-append>.btn,.input-group-sm>.input-group-append>.input-group-text,.input-group-sm>.input-group-prepend>.btn,.input-group-sm>.input-group-prepend>.input-group-text{padding:.25rem .5rem;font-size:.875rem;line-height:1.5;border-radius:.2rem}.input-group-lg>.custom-select,.input-group-sm>.custom-select{padding-right:1.75rem}.input-group>.input-group-append:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group>.input-group-append:last-child>.input-group-text:not(:last-child),.input-group>.input-group-append:not(:last-child)>.btn,.input-group>.input-group-append:not(:last-child)>.input-group-text,.input-group>.input-group-prepend>.btn,.input-group>.input-group-prepend>.input-group-text{border-top-right-radius:0;border-bottom-right-radius:0}.input-group>.input-group-append>.btn,.input-group>.input-group-append>.input-group-text,.input-group>.input-group-prepend:first-child>.btn:not(:first-child),.input-group>.input-group-prepend:first-child>.input-group-text:not(:first-child),.input-group>.input-group-prepend:not(:first-child)>.btn,.input-group>.input-group-prepend:not(:first-child)>.input-group-text{border-top-left-radius:0;border-bottom-left-radius:0}.custom-control{position:relative;display:block;min-height:1.5rem;padding-left:1.5rem}.custom-control-inline{display:inline-flex;margin-right:1rem}.custom-control-input{position:absolute;left:0;z-index:-1;width:1rem;height:1.25rem;opacity:0}.custom-control-input:checked~.custom-control-label:before{color:#fff;border-color:#007bff;background-color:#007bff;box-shadow:none}.custom-control-input:focus~.custom-control-label:before{box-shadow:inset 0 0 0 transparent,none}.custom-control-input:focus:not(:checked)~.custom-control-label:before{border-color:#80bdff}.custom-control-input:not(:disabled):active~.custom-control-label:before{color:#fff;background-color:#b3d7ff;border-color:#b3d7ff;box-shadow:none}.custom-control-input:disabled~.custom-control-label,.custom-control-input[disabled]~.custom-control-label{color:#6c757d}.custom-control-input:disabled~.custom-control-label:before,.custom-control-input[disabled]~.custom-control-label:before{background-color:#e9ecef}.custom-control-label{position:relative;margin-bottom:0;vertical-align:top}.custom-control-label:before{pointer-events:none;background-color:#dee2e6;border:1px solid #adb5bd;box-shadow:inset 0 .25rem .25rem rgba(0,0,0,.1)}.custom-control-label:after,.custom-control-label:before{position:absolute;top:.25rem;left:-1.5rem;display:block;width:1rem;height:1rem;content:""}.custom-control-label:after{background:no-repeat 50%/50% 50%}.custom-checkbox .custom-control-label:before{border-radius:.25rem}.custom-checkbox .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:before{border-color:#007bff;background-color:#007bff;box-shadow:none}.custom-checkbox .custom-control-input:indeterminate~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 4'%3E%3Cpath stroke='%23ffffff' d='M0 2h4'/%3E%3C/svg%3E")}.custom-checkbox .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-checkbox .custom-control-input:disabled:indeterminate~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-radio .custom-control-label:before{border-radius:50%}.custom-radio .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='-4 -4 8 8'%3E%3Ccircle r='3' fill='%23ffffff'/%3E%3C/svg%3E")}.custom-radio .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-switch{padding-left:2.25rem}.custom-switch .custom-control-label:before{left:-2.25rem;width:1.75rem;pointer-events:all;border-radius:.5rem}.custom-switch .custom-control-label:after{top:calc(.25rem + 2px);left:calc(-2.25rem + 2px);width:calc(1rem - 4px);height:calc(1rem - 4px);background-color:#adb5bd;border-radius:.5rem;transition:transform .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-switch .custom-control-label:after{transition:none}}.custom-switch .custom-control-input:checked~.custom-control-label:after{background-color:#dee2e6;transform:translateX(.75rem)}.custom-switch .custom-control-input:disabled:checked~.custom-control-label:before{background-color:rgba(0,123,255,.5)}.custom-select{display:inline-block;width:100%;height:calc(2.25rem + 2px);padding:.375rem 1.75rem .375rem .75rem;font-size:1rem;font-weight:400;line-height:1.5;color:#495057;vertical-align:middle;background:#fff url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 4 5'%3E%3Cpath fill='%23343a40' d='M2 0L0 2h4zm0 5L0 3h4z'/%3E%3C/svg%3E") no-repeat right .75rem center/8px 10px;border:1px solid #ced4da;border-radius:.25rem;box-shadow:inset 0 1px 2px rgba(0,0,0,.075);-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-select:focus{border-color:#80bdff;outline:0;box-shadow:inset 0 1px 2px rgba(0,0,0,.075),none}.custom-select:focus::-ms-value{color:#495057;background-color:#fff}.custom-select[multiple],.custom-select[size]:not([size="1"]){height:auto;padding-right:.75rem;background-image:none}.custom-select:disabled{color:#6c757d;background-color:#e9ecef}.custom-select::-ms-expand{display:none}.custom-select:-moz-focusring{color:transparent;text-shadow:0 0 0 #495057}.custom-select-sm{height:calc(1.8125rem + 2px);padding-top:.25rem;padding-bottom:.25rem;padding-left:.5rem;font-size:75%}.custom-select-lg{height:calc(2.875rem + 2px);padding-top:.5rem;padding-bottom:.5rem;padding-left:1rem;font-size:125%}.custom-file{display:inline-block;margin-bottom:0}.custom-file,.custom-file-input{position:relative;width:100%;height:calc(2.25rem + 2px)}.custom-file-input{z-index:2;margin:0;opacity:0}.custom-file-input:focus~.custom-file-label{border-color:#80bdff;box-shadow:none}.custom-file-input:disabled~.custom-file-label,.custom-file-input[disabled]~.custom-file-label{background-color:#e9ecef}.custom-file-input:lang(en)~.custom-file-label:after{content:"Browse"}.custom-file-input~.custom-file-label[data-browse]:after{content:attr(data-browse)}.custom-file-label{left:0;z-index:1;height:calc(2.25rem + 2px);font-weight:400;background-color:#fff;border:1px solid #ced4da;border-radius:.25rem;box-shadow:none}.custom-file-label,.custom-file-label:after{position:absolute;top:0;right:0;padding:.375rem .75rem;line-height:1.5;color:#495057}.custom-file-label:after{bottom:0;z-index:3;display:block;height:2.25rem;content:"Browse";background-color:#e9ecef;border-left:inherit;border-radius:0 .25rem .25rem 0}.custom-range{width:100%;height:1rem;padding:0;background-color:transparent;-webkit-appearance:none;-moz-appearance:none;appearance:none}.custom-range:focus{outline:none}.custom-range:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 .2rem rgba(0,123,255,.25)}.custom-range::-moz-focus-outer{border:0}.custom-range::-webkit-slider-thumb{width:1rem;height:1rem;margin-top:-.25rem;background-color:#007bff;border:0;border-radius:1rem;box-shadow:0 .1rem .25rem rgba(0,0,0,.1);-webkit-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-webkit-slider-thumb{-webkit-transition:none;transition:none}}.custom-range::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range::-webkit-slider-runnable-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem;box-shadow:inset 0 .25rem .25rem rgba(0,0,0,.1)}.custom-range::-moz-range-thumb{width:1rem;height:1rem;background-color:#007bff;border:0;border-radius:1rem;box-shadow:0 .1rem .25rem rgba(0,0,0,.1);-moz-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;-moz-appearance:none;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-moz-range-thumb{-moz-transition:none;transition:none}}.custom-range::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range::-moz-range-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:#dee2e6;border-color:transparent;border-radius:1rem;box-shadow:inset 0 .25rem .25rem rgba(0,0,0,.1)}.custom-range::-ms-thumb{width:1rem;height:1rem;margin-top:0;margin-right:0;margin-left:0;background-color:#007bff;border:0;border-radius:1rem;box-shadow:0 .1rem .25rem rgba(0,0,0,.1);-ms-transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;appearance:none}@media (prefers-reduced-motion:reduce){.custom-range::-ms-thumb{-ms-transition:none;transition:none}}.custom-range::-ms-thumb:active{background-color:#b3d7ff}.custom-range::-ms-track{width:100%;height:.5rem;color:transparent;cursor:pointer;background-color:transparent;border-color:transparent;border-width:.5rem;box-shadow:inset 0 .25rem .25rem rgba(0,0,0,.1)}.custom-range::-ms-fill-lower,.custom-range::-ms-fill-upper{background-color:#dee2e6;border-radius:1rem}.custom-range::-ms-fill-upper{margin-right:15px}.custom-range:disabled::-webkit-slider-thumb{background-color:#adb5bd}.custom-range:disabled::-webkit-slider-runnable-track{cursor:default}.custom-range:disabled::-moz-range-thumb{background-color:#adb5bd}.custom-range:disabled::-moz-range-track{cursor:default}.custom-range:disabled::-ms-thumb{background-color:#adb5bd}.custom-control-label:before,.custom-file-label,.custom-select{transition:background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.custom-control-label:before,.custom-file-label,.custom-select{transition:none}}.nav{display:flex;flex-wrap:wrap;padding-left:0;margin-bottom:0;list-style:none}.nav-link{display:block;padding:.5rem 1rem}.nav-link:focus,.nav-link:hover{text-decoration:none}.nav-link.disabled{color:#6c757d;pointer-events:none;cursor:default}.nav-tabs{border-bottom:1px solid #dee2e6}.nav-tabs .nav-item{margin-bottom:-1px}.nav-tabs .nav-link{border:1px solid transparent;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.nav-tabs .nav-link:focus,.nav-tabs .nav-link:hover{border-color:#e9ecef #e9ecef #dee2e6}.nav-tabs .nav-link.disabled{color:#6c757d;background-color:transparent;border-color:transparent}.nav-tabs .nav-item.show .nav-link,.nav-tabs .nav-link.active{color:#495057;background-color:#fff;border-color:#dee2e6 #dee2e6 #fff}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-left-radius:0;border-top-right-radius:0}.nav-pills .nav-link{border-radius:.25rem}.nav-pills .nav-link.active,.nav-pills .show>.nav-link{color:#fff;background-color:#007bff}.nav-fill .nav-item{flex:1 1 auto;text-align:center}.nav-justified .nav-item{flex-basis:0;flex-grow:1;text-align:center}.tab-content>.tab-pane{display:none}.tab-content>.active{display:block}.navbar{position:relative;padding:.5rem}.navbar,.navbar .container,.navbar .container-fluid,.navbar .container-lg,.navbar .container-md,.navbar .container-sm,.navbar .container-xl{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between}.navbar-brand{display:inline-block;padding-top:.3125rem;padding-bottom:.3125rem;margin-right:.5rem;font-size:1.25rem;line-height:inherit;white-space:nowrap}.navbar-brand:focus,.navbar-brand:hover{text-decoration:none}.navbar-nav{display:flex;flex-direction:column;padding-left:0;margin-bottom:0;list-style:none}.navbar-nav .nav-link{padding-right:0;padding-left:0}.navbar-nav .dropdown-menu{position:static;float:none}.navbar-text{display:inline-block;padding-top:.5rem;padding-bottom:.5rem}.navbar-collapse{flex-basis:100%;flex-grow:1;align-items:center}.navbar-toggler{padding:.25rem .75rem;font-size:1.25rem;line-height:1;background-color:transparent;border:1px solid transparent;border-radius:.25rem}.navbar-toggler:focus,.navbar-toggler:hover{text-decoration:none}.navbar-toggler-icon{display:inline-block;width:1.5em;height:1.5em;vertical-align:middle;content:"";background:no-repeat 50%;background-size:100% 100%}@media (max-width:575.98px){.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{padding-right:0;padding-left:0}}@media (min-width:576px){.navbar-expand-sm{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-sm .navbar-nav{flex-direction:row}.navbar-expand-sm .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-sm .navbar-nav .nav-link{padding-right:1rem;padding-left:1rem}.navbar-expand-sm>.container,.navbar-expand-sm>.container-fluid,.navbar-expand-sm>.container-lg,.navbar-expand-sm>.container-md,.navbar-expand-sm>.container-sm,.navbar-expand-sm>.container-xl{flex-wrap:nowrap}.navbar-expand-sm .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-sm .navbar-toggler{display:none}}@media (max-width:767.98px){.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{padding-right:0;padding-left:0}}@media (min-width:768px){.navbar-expand-md{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-md .navbar-nav{flex-direction:row}.navbar-expand-md .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-md .navbar-nav .nav-link{padding-right:1rem;padding-left:1rem}.navbar-expand-md>.container,.navbar-expand-md>.container-fluid,.navbar-expand-md>.container-lg,.navbar-expand-md>.container-md,.navbar-expand-md>.container-sm,.navbar-expand-md>.container-xl{flex-wrap:nowrap}.navbar-expand-md .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-md .navbar-toggler{display:none}}@media (max-width:991.98px){.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{padding-right:0;padding-left:0}}@media (min-width:992px){.navbar-expand-lg{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-lg .navbar-nav{flex-direction:row}.navbar-expand-lg .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-lg .navbar-nav .nav-link{padding-right:1rem;padding-left:1rem}.navbar-expand-lg>.container,.navbar-expand-lg>.container-fluid,.navbar-expand-lg>.container-lg,.navbar-expand-lg>.container-md,.navbar-expand-lg>.container-sm,.navbar-expand-lg>.container-xl{flex-wrap:nowrap}.navbar-expand-lg .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-lg .navbar-toggler{display:none}}@media (max-width:1199.98px){.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{padding-right:0;padding-left:0}}@media (min-width:1200px){.navbar-expand-xl{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand-xl .navbar-nav{flex-direction:row}.navbar-expand-xl .navbar-nav .dropdown-menu{position:absolute}.navbar-expand-xl .navbar-nav .nav-link{padding-right:1rem;padding-left:1rem}.navbar-expand-xl>.container,.navbar-expand-xl>.container-fluid,.navbar-expand-xl>.container-lg,.navbar-expand-xl>.container-md,.navbar-expand-xl>.container-sm,.navbar-expand-xl>.container-xl{flex-wrap:nowrap}.navbar-expand-xl .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand-xl .navbar-toggler{display:none}}.navbar-expand{flex-flow:row nowrap;justify-content:flex-start}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{padding-right:0;padding-left:0}.navbar-expand .navbar-nav{flex-direction:row}.navbar-expand .navbar-nav .dropdown-menu{position:absolute}.navbar-expand .navbar-nav .nav-link{padding-right:1rem;padding-left:1rem}.navbar-expand>.container,.navbar-expand>.container-fluid,.navbar-expand>.container-lg,.navbar-expand>.container-md,.navbar-expand>.container-sm,.navbar-expand>.container-xl{flex-wrap:nowrap}.navbar-expand .navbar-collapse{display:flex!important;flex-basis:auto}.navbar-expand .navbar-toggler{display:none}.navbar-light .navbar-brand,.navbar-light .navbar-brand:focus,.navbar-light .navbar-brand:hover{color:rgba(0,0,0,.9)}.navbar-light .navbar-nav .nav-link{color:rgba(0,0,0,.5)}.navbar-light .navbar-nav .nav-link:focus,.navbar-light .navbar-nav .nav-link:hover{color:rgba(0,0,0,.7)}.navbar-light .navbar-nav .nav-link.disabled{color:rgba(0,0,0,.3)}.navbar-light .navbar-nav .active>.nav-link,.navbar-light .navbar-nav .nav-link.active,.navbar-light .navbar-nav .nav-link.show,.navbar-light .navbar-nav .show>.nav-link{color:rgba(0,0,0,.9)}.navbar-light .navbar-toggler{color:rgba(0,0,0,.5);border-color:rgba(0,0,0,.1)}.navbar-light .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(0, 0, 0, 0.5)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-light .navbar-text{color:rgba(0,0,0,.5)}.navbar-light .navbar-text a,.navbar-light .navbar-text a:focus,.navbar-light .navbar-text a:hover{color:rgba(0,0,0,.9)}.navbar-dark .navbar-brand,.navbar-dark .navbar-brand:focus,.navbar-dark .navbar-brand:hover{color:#fff}.navbar-dark .navbar-nav .nav-link{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-nav .nav-link:focus,.navbar-dark .navbar-nav .nav-link:hover{color:#fff}.navbar-dark .navbar-nav .nav-link.disabled{color:hsla(0,0%,100%,.25)}.navbar-dark .navbar-nav .active>.nav-link,.navbar-dark .navbar-nav .nav-link.active,.navbar-dark .navbar-nav .nav-link.show,.navbar-dark .navbar-nav .show>.nav-link{color:#fff}.navbar-dark .navbar-toggler{color:hsla(0,0%,100%,.75);border-color:hsla(0,0%,100%,.1)}.navbar-dark .navbar-toggler-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg viewBox='0 0 30 30' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath stroke='rgba(255, 255, 255, 0.75)' stroke-width='2' stroke-linecap='round' stroke-miterlimit='10' d='M4 7h22M4 15h22M4 23h22'/%3E%3C/svg%3E")}.navbar-dark .navbar-text{color:hsla(0,0%,100%,.75)}.navbar-dark .navbar-text a,.navbar-dark .navbar-text a:focus,.navbar-dark .navbar-text a:hover{color:#fff}.card{position:relative;display:flex;flex-direction:column;min-width:0;word-wrap:break-word;background-color:#fff;background-clip:border-box;border:0 solid rgba(0,0,0,.125);border-radius:.25rem}.card>hr{margin-right:0;margin-left:0}.card>.list-group:first-child .list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card>.list-group:last-child .list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-body{flex:1 1 auto;min-height:1px;padding:1.25rem}.card-title{margin-bottom:.75rem}.card-subtitle{margin-top:-.375rem}.card-subtitle,.card-text:last-child{margin-bottom:0}.card-link:hover{text-decoration:none}.card-link+.card-link{margin-left:1.25rem}.card-header{margin-bottom:0;background-color:rgba(0,0,0,.03);border-bottom:0 solid rgba(0,0,0,.125)}.card-header:first-child{border-radius:.25rem .25rem 0 0}.card-header+.list-group .list-group-item:first-child{border-top:0}.card-footer{padding:.75rem 1.25rem;background-color:rgba(0,0,0,.03);border-top:0 solid rgba(0,0,0,.125)}.card-footer:last-child{border-radius:0 0 .25rem .25rem}.card-header-tabs{margin-bottom:-.75rem;border-bottom:0}.card-header-pills,.card-header-tabs{margin-right:-.625rem;margin-left:-.625rem}.card-img-overlay{position:absolute;top:0;right:0;bottom:0;left:0;padding:1.25rem}.card-img,.card-img-bottom,.card-img-top{flex-shrink:0;width:100%}.card-img,.card-img-top{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.card-img,.card-img-bottom{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.card-deck .card{margin-bottom:7.5px}@media (min-width:576px){.card-deck{display:flex;flex-flow:row wrap;margin-right:-7.5px;margin-left:-7.5px}.card-deck .card{flex:1 0 0%;margin-right:7.5px;margin-bottom:0;margin-left:7.5px}}.card-group>.card{margin-bottom:7.5px}@media (min-width:576px){.card-group{display:flex;flex-flow:row wrap}.card-group>.card{flex:1 0 0%;margin-bottom:0}.card-group>.card+.card{margin-left:0;border-left:0}.card-group>.card:not(:last-child){border-top-right-radius:0;border-bottom-right-radius:0}.card-group>.card:not(:last-child) .card-header,.card-group>.card:not(:last-child) .card-img-top{border-top-right-radius:0}.card-group>.card:not(:last-child) .card-footer,.card-group>.card:not(:last-child) .card-img-bottom{border-bottom-right-radius:0}.card-group>.card:not(:first-child){border-top-left-radius:0;border-bottom-left-radius:0}.card-group>.card:not(:first-child) .card-header,.card-group>.card:not(:first-child) .card-img-top{border-top-left-radius:0}.card-group>.card:not(:first-child) .card-footer,.card-group>.card:not(:first-child) .card-img-bottom{border-bottom-left-radius:0}}.card-columns .card{margin-bottom:.75rem}@media (min-width:576px){.card-columns{-moz-column-count:3;column-count:3;-moz-column-gap:1.25rem;column-gap:1.25rem;orphans:1;widows:1}.card-columns .card{display:inline-block;width:100%}}.accordion>.card{overflow:hidden}.accordion>.card:not(:last-of-type){border-bottom:0;border-bottom-right-radius:0;border-bottom-left-radius:0}.accordion>.card:not(:first-of-type){border-top-left-radius:0;border-top-right-radius:0}.accordion>.card>.card-header{border-radius:0;margin-bottom:0}.breadcrumb{display:flex;flex-wrap:wrap;padding:.75rem 1rem;margin-bottom:1rem;list-style:none;background-color:#e9ecef;border-radius:.25rem}.breadcrumb-item+.breadcrumb-item{padding-left:.5rem}.breadcrumb-item+.breadcrumb-item:before{display:inline-block;padding-right:.5rem;color:#6c757d;content:"/"}.breadcrumb-item+.breadcrumb-item:hover:before{text-decoration:underline;text-decoration:none}.breadcrumb-item.active{color:#6c757d}.pagination{display:flex;padding-left:0;list-style:none;border-radius:.25rem}.page-link{position:relative;display:block;padding:.5rem .75rem;margin-left:-1px;line-height:1.25;color:#007bff;background-color:#fff;border:1px solid #dee2e6}.page-link:hover{z-index:2;color:#0056b3;text-decoration:none;background-color:#e9ecef;border-color:#dee2e6}.page-link:focus{z-index:3;outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.page-item:first-child .page-link{margin-left:0;border-top-left-radius:.25rem;border-bottom-left-radius:.25rem}.page-item:last-child .page-link{border-top-right-radius:.25rem;border-bottom-right-radius:.25rem}.page-item.active .page-link{z-index:3;color:#fff;background-color:#007bff;border-color:#007bff}.page-item.disabled .page-link{color:#6c757d;pointer-events:none;cursor:auto;background-color:#fff;border-color:#dee2e6}.pagination-lg .page-link{padding:.75rem 1.5rem;font-size:1.25rem;line-height:1.5}.pagination-lg .page-item:first-child .page-link{border-top-left-radius:.3rem;border-bottom-left-radius:.3rem}.pagination-lg .page-item:last-child .page-link{border-top-right-radius:.3rem;border-bottom-right-radius:.3rem}.pagination-sm .page-link{padding:.25rem .5rem;font-size:.875rem;line-height:1.5}.pagination-sm .page-item:first-child .page-link{border-top-left-radius:.2rem;border-bottom-left-radius:.2rem}.pagination-sm .page-item:last-child .page-link{border-top-right-radius:.2rem;border-bottom-right-radius:.2rem}.badge{display:inline-block;padding:.25em .4em;font-size:75%;font-weight:700;line-height:1;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25rem;transition:color .15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out}@media (prefers-reduced-motion:reduce){.badge{transition:none}}a.badge:focus,a.badge:hover{text-decoration:none}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.badge-pill{padding-right:.6em;padding-left:.6em;border-radius:10rem}.badge-primary{color:#fff;background-color:#007bff}a.badge-primary:focus,a.badge-primary:hover{color:#fff;background-color:#0062cc}a.badge-primary.focus,a.badge-primary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(0,123,255,.5)}.badge-secondary{color:#fff;background-color:#6c757d}a.badge-secondary:focus,a.badge-secondary:hover{color:#fff;background-color:#545b62}a.badge-secondary.focus,a.badge-secondary:focus{outline:0;box-shadow:0 0 0 .2rem rgba(108,117,125,.5)}.badge-success{color:#fff;background-color:#28a745}a.badge-success:focus,a.badge-success:hover{color:#fff;background-color:#1e7e34}a.badge-success.focus,a.badge-success:focus{outline:0;box-shadow:0 0 0 .2rem rgba(40,167,69,.5)}.badge-info{color:#fff;background-color:#17a2b8}a.badge-info:focus,a.badge-info:hover{color:#fff;background-color:#117a8b}a.badge-info.focus,a.badge-info:focus{outline:0;box-shadow:0 0 0 .2rem rgba(23,162,184,.5)}.badge-warning{color:#1f2d3d;background-color:#ffc107}a.badge-warning:focus,a.badge-warning:hover{color:#1f2d3d;background-color:#d39e00}a.badge-warning.focus,a.badge-warning:focus{outline:0;box-shadow:0 0 0 .2rem rgba(255,193,7,.5)}.badge-danger{color:#fff;background-color:#dc3545}a.badge-danger:focus,a.badge-danger:hover{color:#fff;background-color:#bd2130}a.badge-danger.focus,a.badge-danger:focus{outline:0;box-shadow:0 0 0 .2rem rgba(220,53,69,.5)}.badge-light{color:#1f2d3d;background-color:#f8f9fa}a.badge-light:focus,a.badge-light:hover{color:#1f2d3d;background-color:#dae0e5}a.badge-light.focus,a.badge-light:focus{outline:0;box-shadow:0 0 0 .2rem rgba(248,249,250,.5)}.badge-dark{color:#fff;background-color:#343a40}a.badge-dark:focus,a.badge-dark:hover{color:#fff;background-color:#1d2124}a.badge-dark.focus,a.badge-dark:focus{outline:0;box-shadow:0 0 0 .2rem rgba(52,58,64,.5)}.jumbotron{padding:2rem 1rem;margin-bottom:2rem;background-color:#e9ecef;border-radius:.3rem}@media (min-width:576px){.jumbotron{padding:4rem 2rem}}.jumbotron-fluid{padding-right:0;padding-left:0;border-radius:0}.alert{position:relative;padding:.75rem 1.25rem;margin-bottom:1rem;border:1px solid transparent;border-radius:.25rem}.alert-heading{color:inherit}.alert-link{font-weight:700}.alert-dismissible{padding-right:4rem}.alert-dismissible .close,.alert-dismissible .mailbox-attachment-close{position:absolute;top:0;right:0;padding:.75rem 1.25rem;color:inherit}.alert-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-primary hr{border-top-color:#9fcdff}.alert-primary .alert-link{color:#002752}.alert-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-secondary hr{border-top-color:#c8cbcf}.alert-secondary .alert-link{color:#202326}.alert-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-success hr{border-top-color:#b1dfbb}.alert-success .alert-link{color:#0b2e13}.alert-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-info hr{border-top-color:#abdde5}.alert-info .alert-link{color:#062c33}.alert-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-warning hr{border-top-color:#ffe8a1}.alert-warning .alert-link{color:#533f03}.alert-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-danger hr{border-top-color:#f1b0b7}.alert-danger .alert-link{color:#491217}.alert-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-light hr{border-top-color:#ececf6}.alert-light .alert-link{color:#686868}.alert-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-dark hr{border-top-color:#b9bbbe}.alert-dark .alert-link{color:#040505}@-webkit-keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}@keyframes progress-bar-stripes{0%{background-position:1rem 0}to{background-position:0 0}}.progress{height:1rem;font-size:.75rem;background-color:#e9ecef;border-radius:.25rem;box-shadow:inset 0 .1rem .1rem rgba(0,0,0,.1)}.progress,.progress-bar{display:flex;overflow:hidden}.progress-bar{flex-direction:column;justify-content:center;color:#fff;text-align:center;white-space:nowrap;background-color:#007bff;transition:width .6s ease}@media (prefers-reduced-motion:reduce){.progress-bar{transition:none}}.progress-bar-striped{background-image:linear-gradient(45deg,hsla(0,0%,100%,.15) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.15) 0,hsla(0,0%,100%,.15) 75%,transparent 0,transparent);background-size:1rem 1rem}.progress-bar-animated{-webkit-animation:progress-bar-stripes 1s linear infinite;animation:progress-bar-stripes 1s linear infinite}@media (prefers-reduced-motion:reduce){.progress-bar-animated{-webkit-animation:none;animation:none}}.media{display:flex;align-items:flex-start}.media-body{flex:1}.list-group{display:flex;flex-direction:column;padding-left:0;margin-bottom:0}.list-group-item-action{width:100%;color:#495057;text-align:inherit}.list-group-item-action:focus,.list-group-item-action:hover{z-index:1;color:#495057;text-decoration:none;background-color:#f8f9fa}.list-group-item-action:active{color:#212529;background-color:#e9ecef}.list-group-item{position:relative;display:block;padding:.75rem 1.25rem;background-color:#fff;border:1px solid rgba(0,0,0,.125)}.list-group-item:first-child{border-top-left-radius:.25rem;border-top-right-radius:.25rem}.list-group-item:last-child{border-bottom-right-radius:.25rem;border-bottom-left-radius:.25rem}.list-group-item.disabled,.list-group-item:disabled{color:#6c757d;pointer-events:none;background-color:#fff}.list-group-item.active{z-index:2;color:#fff;background-color:#007bff;border-color:#007bff}.list-group-item+.list-group-item{border-top-width:0}.list-group-item+.list-group-item.active{margin-top:-1px;border-top-width:1px}.list-group-horizontal{flex-direction:row}.list-group-horizontal .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal .list-group-item.active{margin-top:0}.list-group-horizontal .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}@media (min-width:576px){.list-group-horizontal-sm{flex-direction:row}.list-group-horizontal-sm .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-sm .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-sm .list-group-item.active{margin-top:0}.list-group-horizontal-sm .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-sm .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:768px){.list-group-horizontal-md{flex-direction:row}.list-group-horizontal-md .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-md .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-md .list-group-item.active{margin-top:0}.list-group-horizontal-md .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-md .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:992px){.list-group-horizontal-lg{flex-direction:row}.list-group-horizontal-lg .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-lg .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-lg .list-group-item.active{margin-top:0}.list-group-horizontal-lg .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-lg .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}@media (min-width:1200px){.list-group-horizontal-xl{flex-direction:row}.list-group-horizontal-xl .list-group-item:first-child{border-bottom-left-radius:.25rem;border-top-right-radius:0}.list-group-horizontal-xl .list-group-item:last-child{border-top-right-radius:.25rem;border-bottom-left-radius:0}.list-group-horizontal-xl .list-group-item.active{margin-top:0}.list-group-horizontal-xl .list-group-item+.list-group-item{border-top-width:1px;border-left-width:0}.list-group-horizontal-xl .list-group-item+.list-group-item.active{margin-left:-1px;border-left-width:1px}}.list-group-flush .list-group-item{border-right-width:0;border-left-width:0;border-radius:0}.list-group-flush .list-group-item:first-child{border-top-width:0}.list-group-flush:last-child .list-group-item:last-child{border-bottom-width:0}.list-group-item-primary{color:#004085;background-color:#b8daff}.list-group-item-primary.list-group-item-action:focus,.list-group-item-primary.list-group-item-action:hover{color:#004085;background-color:#9fcdff}.list-group-item-primary.list-group-item-action.active{color:#fff;background-color:#004085;border-color:#004085}.list-group-item-secondary{color:#383d41;background-color:#d6d8db}.list-group-item-secondary.list-group-item-action:focus,.list-group-item-secondary.list-group-item-action:hover{color:#383d41;background-color:#c8cbcf}.list-group-item-secondary.list-group-item-action.active{color:#fff;background-color:#383d41;border-color:#383d41}.list-group-item-success{color:#155724;background-color:#c3e6cb}.list-group-item-success.list-group-item-action:focus,.list-group-item-success.list-group-item-action:hover{color:#155724;background-color:#b1dfbb}.list-group-item-success.list-group-item-action.active{color:#fff;background-color:#155724;border-color:#155724}.list-group-item-info{color:#0c5460;background-color:#bee5eb}.list-group-item-info.list-group-item-action:focus,.list-group-item-info.list-group-item-action:hover{color:#0c5460;background-color:#abdde5}.list-group-item-info.list-group-item-action.active{color:#fff;background-color:#0c5460;border-color:#0c5460}.list-group-item-warning{color:#856404;background-color:#ffeeba}.list-group-item-warning.list-group-item-action:focus,.list-group-item-warning.list-group-item-action:hover{color:#856404;background-color:#ffe8a1}.list-group-item-warning.list-group-item-action.active{color:#fff;background-color:#856404;border-color:#856404}.list-group-item-danger{color:#721c24;background-color:#f5c6cb}.list-group-item-danger.list-group-item-action:focus,.list-group-item-danger.list-group-item-action:hover{color:#721c24;background-color:#f1b0b7}.list-group-item-danger.list-group-item-action.active{color:#fff;background-color:#721c24;border-color:#721c24}.list-group-item-light{color:#818182;background-color:#fdfdfe}.list-group-item-light.list-group-item-action:focus,.list-group-item-light.list-group-item-action:hover{color:#818182;background-color:#ececf6}.list-group-item-light.list-group-item-action.active{color:#fff;background-color:#818182;border-color:#818182}.list-group-item-dark{color:#1b1e21;background-color:#c6c8ca}.list-group-item-dark.list-group-item-action:focus,.list-group-item-dark.list-group-item-action:hover{color:#1b1e21;background-color:#b9bbbe}.list-group-item-dark.list-group-item-action.active{color:#fff;background-color:#1b1e21;border-color:#1b1e21}.close,.mailbox-attachment-close{float:right;font-size:1.5rem;font-weight:700;line-height:1;color:#000;text-shadow:0 1px 0 #fff;opacity:.5}.close:hover,.mailbox-attachment-close:hover{color:#000;text-decoration:none}.close:not(:disabled):not(.disabled):focus,.close:not(:disabled):not(.disabled):hover,.mailbox-attachment-close:not(:disabled):not(.disabled):focus,.mailbox-attachment-close:not(:disabled):not(.disabled):hover{opacity:.75}button.close,button.mailbox-attachment-close{padding:0;background-color:transparent;border:0;-webkit-appearance:none;-moz-appearance:none;appearance:none}a.close.disabled,a.disabled.mailbox-attachment-close{pointer-events:none}.toast{max-width:350px;overflow:hidden;font-size:.875rem;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border:1px solid rgba(0,0,0,.1);box-shadow:0 .25rem .75rem rgba(0,0,0,.1);-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);opacity:0;border-radius:.25rem}.toast:not(:last-child){margin-bottom:.75rem}.toast.showing{opacity:1}.toast.show{display:block;opacity:1}.toast.hide{display:none}.toast-header{display:flex;align-items:center;padding:.25rem .75rem;color:#6c757d;background-color:hsla(0,0%,100%,.85);background-clip:padding-box;border-bottom:1px solid rgba(0,0,0,.05)}.toast-body{padding:.75rem}.modal-open{overflow:hidden}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal{position:fixed;top:0;left:0;z-index:1050;display:none;width:100%;height:100%;overflow:hidden;outline:0}.modal-dialog{position:relative;width:auto;margin:.5rem;pointer-events:none}.modal.fade .modal-dialog{transition:transform .3s ease-out;transform:translateY(-50px)}@media (prefers-reduced-motion:reduce){.modal.fade .modal-dialog{transition:none}}.modal.show .modal-dialog{transform:none}.modal.modal-static .modal-dialog{transform:scale(1.02)}.modal-dialog-scrollable{display:flex;max-height:calc(100% - 1rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 1rem);overflow:hidden}.modal-dialog-scrollable .modal-footer,.modal-dialog-scrollable .modal-header{flex-shrink:0}.modal-dialog-scrollable .modal-body{overflow-y:auto}.modal-dialog-centered{display:flex;align-items:center;min-height:calc(100% - 1rem)}.modal-dialog-centered:before{display:block;height:calc(100vh - 1rem);content:""}.modal-dialog-centered.modal-dialog-scrollable{flex-direction:column;justify-content:center;height:100%}.modal-dialog-centered.modal-dialog-scrollable .modal-content{max-height:none}.modal-dialog-centered.modal-dialog-scrollable:before{content:none}.modal-content{position:relative;display:flex;flex-direction:column;width:100%;pointer-events:auto;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;box-shadow:0 .25rem .5rem rgba(0,0,0,.5);outline:0}.modal-backdrop{position:fixed;top:0;left:0;z-index:1040;width:100vw;height:100vh;background-color:#000}.modal-backdrop.fade{opacity:0}.modal-backdrop.show{opacity:.5}.modal-header{display:flex;align-items:flex-start;justify-content:space-between;padding:1rem;border-bottom:1px solid #e9ecef;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.modal-header .close,.modal-header .mailbox-attachment-close{padding:1rem;margin:-1rem -1rem -1rem auto}.modal-title{margin-bottom:0;line-height:1.5}.modal-body{position:relative;flex:1 1 auto;padding:1rem}.modal-footer{display:flex;flex-wrap:wrap;align-items:center;justify-content:flex-end;padding:.75rem;border-top:1px solid #e9ecef;border-bottom-right-radius:calc(.3rem - 1px);border-bottom-left-radius:calc(.3rem - 1px)}.modal-footer>*{margin:.25rem}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:576px){.modal-dialog{max-width:500px;margin:1.75rem auto}.modal-dialog-scrollable{max-height:calc(100% - 3.5rem)}.modal-dialog-scrollable .modal-content{max-height:calc(100vh - 3.5rem)}.modal-dialog-centered{min-height:calc(100% - 3.5rem)}.modal-dialog-centered:before{height:calc(100vh - 3.5rem)}.modal-content{box-shadow:0 .5rem 1rem rgba(0,0,0,.5)}.modal-sm{max-width:300px}}@media (min-width:992px){.modal-lg,.modal-xl{max-width:800px}}@media (min-width:1200px){.modal-xl{max-width:1140px}}.tooltip{position:absolute;z-index:1070;display:block;margin:0;font-family:Source Sans Pro,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;opacity:0}.tooltip.show{opacity:.9}.tooltip .arrow{position:absolute;display:block;width:.8rem;height:.4rem}.tooltip .arrow:before{position:absolute;content:"";border-color:transparent;border-style:solid}.bs-tooltip-auto[x-placement^=top],.bs-tooltip-top{padding:.4rem 0}.bs-tooltip-auto[x-placement^=top] .arrow,.bs-tooltip-top .arrow{bottom:0}.bs-tooltip-auto[x-placement^=top] .arrow:before,.bs-tooltip-top .arrow:before{top:0;border-width:.4rem .4rem 0;border-top-color:#000}.bs-tooltip-auto[x-placement^=right],.bs-tooltip-right{padding:0 .4rem}.bs-tooltip-auto[x-placement^=right] .arrow,.bs-tooltip-right .arrow{left:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=right] .arrow:before,.bs-tooltip-right .arrow:before{right:0;border-width:.4rem .4rem .4rem 0;border-right-color:#000}.bs-tooltip-auto[x-placement^=bottom],.bs-tooltip-bottom{padding:.4rem 0}.bs-tooltip-auto[x-placement^=bottom] .arrow,.bs-tooltip-bottom .arrow{top:0}.bs-tooltip-auto[x-placement^=bottom] .arrow:before,.bs-tooltip-bottom .arrow:before{bottom:0;border-width:0 .4rem .4rem;border-bottom-color:#000}.bs-tooltip-auto[x-placement^=left],.bs-tooltip-left{padding:0 .4rem}.bs-tooltip-auto[x-placement^=left] .arrow,.bs-tooltip-left .arrow{right:0;width:.4rem;height:.8rem}.bs-tooltip-auto[x-placement^=left] .arrow:before,.bs-tooltip-left .arrow:before{left:0;border-width:.4rem 0 .4rem .4rem;border-left-color:#000}.tooltip-inner{max-width:200px;padding:.25rem .5rem;color:#fff;text-align:center;background-color:#000;border-radius:.25rem}.popover{top:0;left:0;z-index:1060;max-width:276px;font-family:Source Sans Pro,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;font-size:.875rem;word-wrap:break-word;background-color:#fff;background-clip:padding-box;border:1px solid rgba(0,0,0,.2);border-radius:.3rem;box-shadow:0 .25rem .5rem rgba(0,0,0,.2)}.popover,.popover .arrow{position:absolute;display:block}.popover .arrow{width:1rem;height:.5rem;margin:0 .3rem}.popover .arrow:after,.popover .arrow:before{position:absolute;display:block;content:"";border-color:transparent;border-style:solid}.bs-popover-auto[x-placement^=top],.bs-popover-top{margin-bottom:.5rem}.bs-popover-auto[x-placement^=top]>.arrow,.bs-popover-top>.arrow{bottom:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=top]>.arrow:before,.bs-popover-top>.arrow:before{bottom:0;border-width:.5rem .5rem 0;border-top-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=top]>.arrow:after,.bs-popover-top>.arrow:after{bottom:1px;border-width:.5rem .5rem 0;border-top-color:#fff}.bs-popover-auto[x-placement^=right],.bs-popover-right{margin-left:.5rem}.bs-popover-auto[x-placement^=right]>.arrow,.bs-popover-right>.arrow{left:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=right]>.arrow:before,.bs-popover-right>.arrow:before{left:0;border-width:.5rem .5rem .5rem 0;border-right-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=right]>.arrow:after,.bs-popover-right>.arrow:after{left:1px;border-width:.5rem .5rem .5rem 0;border-right-color:#fff}.bs-popover-auto[x-placement^=bottom],.bs-popover-bottom{margin-top:.5rem}.bs-popover-auto[x-placement^=bottom]>.arrow,.bs-popover-bottom>.arrow{top:calc(-.5rem - 1px)}.bs-popover-auto[x-placement^=bottom]>.arrow:before,.bs-popover-bottom>.arrow:before{top:0;border-width:0 .5rem .5rem;border-bottom-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=bottom]>.arrow:after,.bs-popover-bottom>.arrow:after{top:1px;border-width:0 .5rem .5rem;border-bottom-color:#fff}.bs-popover-auto[x-placement^=bottom] .popover-header:before,.bs-popover-bottom .popover-header:before{position:absolute;top:0;left:50%;display:block;width:1rem;margin-left:-.5rem;content:"";border-bottom:1px solid #f7f7f7}.bs-popover-auto[x-placement^=left],.bs-popover-left{margin-right:.5rem}.bs-popover-auto[x-placement^=left]>.arrow,.bs-popover-left>.arrow{right:calc(-.5rem - 1px);width:.5rem;height:1rem;margin:.3rem 0}.bs-popover-auto[x-placement^=left]>.arrow:before,.bs-popover-left>.arrow:before{right:0;border-width:.5rem 0 .5rem .5rem;border-left-color:rgba(0,0,0,.25)}.bs-popover-auto[x-placement^=left]>.arrow:after,.bs-popover-left>.arrow:after{right:1px;border-width:.5rem 0 .5rem .5rem;border-left-color:#fff}.popover-header{padding:.5rem .75rem;margin-bottom:0;font-size:1rem;color:inherit;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-top-left-radius:calc(.3rem - 1px);border-top-right-radius:calc(.3rem - 1px)}.popover-header:empty{display:none}.popover-body{padding:.5rem .75rem;color:#212529}.carousel{position:relative}.carousel.pointer-event{touch-action:pan-y}.carousel-inner{position:relative;width:100%;overflow:hidden}.carousel-inner:after{display:block;clear:both;content:""}.carousel-item{position:relative;display:none;float:left;width:100%;margin-right:-100%;-webkit-backface-visibility:hidden;backface-visibility:hidden;transition:transform .6s ease}@media (prefers-reduced-motion:reduce){.carousel-item{transition:none}}.carousel-item-next,.carousel-item-prev,.carousel-item.active{display:block}.active.carousel-item-right,.carousel-item-next:not(.carousel-item-left){transform:translateX(100%)}.active.carousel-item-left,.carousel-item-prev:not(.carousel-item-right){transform:translateX(-100%)}.carousel-fade .carousel-item{opacity:0;transition-property:opacity;transform:none}.carousel-fade .carousel-item-next.carousel-item-left,.carousel-fade .carousel-item-prev.carousel-item-right,.carousel-fade .carousel-item.active{z-index:1;opacity:1}.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{z-index:0;opacity:0;transition:opacity 0s .6s}@media (prefers-reduced-motion:reduce){.carousel-fade .active.carousel-item-left,.carousel-fade .active.carousel-item-right{transition:none}}.carousel-control-next,.carousel-control-prev{position:absolute;top:0;bottom:0;z-index:1;display:flex;align-items:center;justify-content:center;width:15%;color:#fff;text-align:center;opacity:.5;transition:opacity .15s ease}@media (prefers-reduced-motion:reduce){.carousel-control-next,.carousel-control-prev{transition:none}}.carousel-control-next:focus,.carousel-control-next:hover,.carousel-control-prev:focus,.carousel-control-prev:hover{color:#fff;text-decoration:none;outline:0;opacity:.9}.carousel-control-prev{left:0}.carousel-control-next{right:0}.carousel-control-next-icon,.carousel-control-prev-icon{display:inline-block;width:20px;height:20px;background:no-repeat 50%/100% 100%}.carousel-control-prev-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23ffffff' viewBox='0 0 8 8'%3E%3Cpath d='M5.25 0l-4 4 4 4 1.5-1.5-2.5-2.5 2.5-2.5-1.5-1.5z'/%3E%3C/svg%3E")}.carousel-control-next-icon{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' fill='%23ffffff' viewBox='0 0 8 8'%3E%3Cpath d='M2.75 0l-1.5 1.5 2.5 2.5-2.5 2.5 1.5 1.5 4-4-4-4z'/%3E%3C/svg%3E")}.carousel-indicators{position:absolute;right:0;bottom:0;left:0;z-index:15;display:flex;justify-content:center;padding-left:0;margin-right:15%;margin-left:15%;list-style:none}.carousel-indicators li{box-sizing:content-box;flex:0 1 auto;width:30px;height:3px;margin-right:3px;margin-left:3px;text-indent:-999px;cursor:pointer;background-color:#fff;background-clip:padding-box;border-top:10px solid transparent;border-bottom:10px solid transparent;opacity:.5;transition:opacity .6s ease}@media (prefers-reduced-motion:reduce){.carousel-indicators li{transition:none}}.carousel-indicators .active{opacity:1}.carousel-caption{position:absolute;right:15%;bottom:20px;left:15%;z-index:10;padding-top:20px;padding-bottom:20px;color:#fff;text-align:center}@-webkit-keyframes spinner-border{to{transform:rotate(1turn)}}@keyframes spinner-border{to{transform:rotate(1turn)}}.spinner-border{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;border:.25em solid;border-right:.25em solid transparent;border-radius:50%;-webkit-animation:spinner-border .75s linear infinite;animation:spinner-border .75s linear infinite}.spinner-border-sm{width:1rem;height:1rem;border-width:.2em}@-webkit-keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1}}@keyframes spinner-grow{0%{transform:scale(0)}50%{opacity:1}}.spinner-grow{display:inline-block;width:2rem;height:2rem;vertical-align:text-bottom;background-color:currentColor;border-radius:50%;opacity:0;-webkit-animation:spinner-grow .75s linear infinite;animation:spinner-grow .75s linear infinite}.spinner-grow-sm{width:1rem;height:1rem}.align-baseline{vertical-align:baseline!important}.align-top{vertical-align:top!important}.align-middle{vertical-align:middle!important}.align-bottom{vertical-align:bottom!important}.align-text-bottom{vertical-align:text-bottom!important}.align-text-top{vertical-align:text-top!important}a.bg-primary:focus,a.bg-primary:hover,button.bg-primary:focus,button.bg-primary:hover{background-color:#0062cc!important}a.bg-secondary:focus,a.bg-secondary:hover,button.bg-secondary:focus,button.bg-secondary:hover{background-color:#545b62!important}a.bg-success:focus,a.bg-success:hover,button.bg-success:focus,button.bg-success:hover{background-color:#1e7e34!important}a.bg-info:focus,a.bg-info:hover,button.bg-info:focus,button.bg-info:hover{background-color:#117a8b!important}a.bg-warning:focus,a.bg-warning:hover,button.bg-warning:focus,button.bg-warning:hover{background-color:#d39e00!important}a.bg-danger:focus,a.bg-danger:hover,button.bg-danger:focus,button.bg-danger:hover{background-color:#bd2130!important}a.bg-light:focus,a.bg-light:hover,button.bg-light:focus,button.bg-light:hover{background-color:#dae0e5!important}a.bg-dark:focus,a.bg-dark:hover,button.bg-dark:focus,button.bg-dark:hover{background-color:#1d2124!important}.bg-transparent{background-color:transparent!important}.border{border:1px solid #dee2e6!important}.border-top{border-top:1px solid #dee2e6!important}.border-right{border-right:1px solid #dee2e6!important}.border-bottom{border-bottom:1px solid #dee2e6!important}.border-left{border-left:1px solid #dee2e6!important}.border-0{border:0!important}.border-top-0{border-top:0!important}.border-right-0{border-right:0!important}.border-bottom-0{border-bottom:0!important}.border-left-0{border-left:0!important}.border-primary{border-color:#007bff!important}.border-secondary{border-color:#6c757d!important}.border-success{border-color:#28a745!important}.border-info{border-color:#17a2b8!important}.border-warning{border-color:#ffc107!important}.border-danger{border-color:#dc3545!important}.border-light{border-color:#f8f9fa!important}.border-dark{border-color:#343a40!important}.border-white{border-color:#fff!important}.rounded-sm{border-radius:.2rem!important}.rounded{border-radius:.25rem!important}.rounded-top{border-top-left-radius:.25rem!important}.rounded-right,.rounded-top{border-top-right-radius:.25rem!important}.rounded-bottom,.rounded-right{border-bottom-right-radius:.25rem!important}.rounded-bottom,.rounded-left{border-bottom-left-radius:.25rem!important}.rounded-left{border-top-left-radius:.25rem!important}.rounded-lg{border-radius:.3rem!important}.rounded-circle{border-radius:50%!important}.rounded-pill{border-radius:50rem!important}.rounded-0{border-radius:0!important}.clearfix:after{display:block;clear:both;content:""}.d-none{display:none!important}.d-inline{display:inline!important}.d-inline-block{display:inline-block!important}.d-block{display:block!important}.d-table{display:table!important}.d-table-row{display:table-row!important}.d-table-cell{display:table-cell!important}.d-flex{display:flex!important}.d-inline-flex{display:inline-flex!important}@media (min-width:576px){.d-sm-none{display:none!important}.d-sm-inline{display:inline!important}.d-sm-inline-block{display:inline-block!important}.d-sm-block{display:block!important}.d-sm-table{display:table!important}.d-sm-table-row{display:table-row!important}.d-sm-table-cell{display:table-cell!important}.d-sm-flex{display:flex!important}.d-sm-inline-flex{display:inline-flex!important}}@media (min-width:768px){.d-md-none{display:none!important}.d-md-inline{display:inline!important}.d-md-inline-block{display:inline-block!important}.d-md-block{display:block!important}.d-md-table{display:table!important}.d-md-table-row{display:table-row!important}.d-md-table-cell{display:table-cell!important}.d-md-flex{display:flex!important}.d-md-inline-flex{display:inline-flex!important}}@media (min-width:992px){.d-lg-none{display:none!important}.d-lg-inline{display:inline!important}.d-lg-inline-block{display:inline-block!important}.d-lg-block{display:block!important}.d-lg-table{display:table!important}.d-lg-table-row{display:table-row!important}.d-lg-table-cell{display:table-cell!important}.d-lg-flex{display:flex!important}.d-lg-inline-flex{display:inline-flex!important}}@media (min-width:1200px){.d-xl-none{display:none!important}.d-xl-inline{display:inline!important}.d-xl-inline-block{display:inline-block!important}.d-xl-block{display:block!important}.d-xl-table{display:table!important}.d-xl-table-row{display:table-row!important}.d-xl-table-cell{display:table-cell!important}.d-xl-flex{display:flex!important}.d-xl-inline-flex{display:inline-flex!important}}@media print{.d-print-none{display:none!important}.d-print-inline{display:inline!important}.d-print-inline-block{display:inline-block!important}.d-print-block{display:block!important}.d-print-table{display:table!important}.d-print-table-row{display:table-row!important}.d-print-table-cell{display:table-cell!important}.d-print-flex{display:flex!important}.d-print-inline-flex{display:inline-flex!important}}.embed-responsive{position:relative;display:block;width:100%;padding:0;overflow:hidden}.embed-responsive:before{display:block;content:""}.embed-responsive .embed-responsive-item,.embed-responsive embed,.embed-responsive iframe,.embed-responsive object,.embed-responsive video{position:absolute;top:0;bottom:0;left:0;width:100%;height:100%;border:0}.embed-responsive-21by9:before{padding-top:42.857143%}.embed-responsive-16by9:before{padding-top:56.25%}.embed-responsive-4by3:before{padding-top:75%}.embed-responsive-1by1:before{padding-top:100%}.flex-row{flex-direction:row!important}.flex-column{flex-direction:column!important}.flex-row-reverse{flex-direction:row-reverse!important}.flex-column-reverse{flex-direction:column-reverse!important}.flex-wrap{flex-wrap:wrap!important}.flex-nowrap{flex-wrap:nowrap!important}.flex-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-fill{flex:1 1 auto!important}.flex-grow-0{flex-grow:0!important}.flex-grow-1{flex-grow:1!important}.flex-shrink-0{flex-shrink:0!important}.flex-shrink-1{flex-shrink:1!important}.justify-content-start{justify-content:flex-start!important}.justify-content-end{justify-content:flex-end!important}.justify-content-center{justify-content:center!important}.justify-content-between{justify-content:space-between!important}.justify-content-around{justify-content:space-around!important}.align-items-start{align-items:flex-start!important}.align-items-end{align-items:flex-end!important}.align-items-center{align-items:center!important}.align-items-baseline{align-items:baseline!important}.align-items-stretch{align-items:stretch!important}.align-content-start{align-content:flex-start!important}.align-content-end{align-content:flex-end!important}.align-content-center{align-content:center!important}.align-content-between{align-content:space-between!important}.align-content-around{align-content:space-around!important}.align-content-stretch{align-content:stretch!important}.align-self-auto{align-self:auto!important}.align-self-start{align-self:flex-start!important}.align-self-end{align-self:flex-end!important}.align-self-center{align-self:center!important}.align-self-baseline{align-self:baseline!important}.align-self-stretch{align-self:stretch!important}@media (min-width:576px){.flex-sm-row{flex-direction:row!important}.flex-sm-column{flex-direction:column!important}.flex-sm-row-reverse{flex-direction:row-reverse!important}.flex-sm-column-reverse{flex-direction:column-reverse!important}.flex-sm-wrap{flex-wrap:wrap!important}.flex-sm-nowrap{flex-wrap:nowrap!important}.flex-sm-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-sm-fill{flex:1 1 auto!important}.flex-sm-grow-0{flex-grow:0!important}.flex-sm-grow-1{flex-grow:1!important}.flex-sm-shrink-0{flex-shrink:0!important}.flex-sm-shrink-1{flex-shrink:1!important}.justify-content-sm-start{justify-content:flex-start!important}.justify-content-sm-end{justify-content:flex-end!important}.justify-content-sm-center{justify-content:center!important}.justify-content-sm-between{justify-content:space-between!important}.justify-content-sm-around{justify-content:space-around!important}.align-items-sm-start{align-items:flex-start!important}.align-items-sm-end{align-items:flex-end!important}.align-items-sm-center{align-items:center!important}.align-items-sm-baseline{align-items:baseline!important}.align-items-sm-stretch{align-items:stretch!important}.align-content-sm-start{align-content:flex-start!important}.align-content-sm-end{align-content:flex-end!important}.align-content-sm-center{align-content:center!important}.align-content-sm-between{align-content:space-between!important}.align-content-sm-around{align-content:space-around!important}.align-content-sm-stretch{align-content:stretch!important}.align-self-sm-auto{align-self:auto!important}.align-self-sm-start{align-self:flex-start!important}.align-self-sm-end{align-self:flex-end!important}.align-self-sm-center{align-self:center!important}.align-self-sm-baseline{align-self:baseline!important}.align-self-sm-stretch{align-self:stretch!important}}@media (min-width:768px){.flex-md-row{flex-direction:row!important}.flex-md-column{flex-direction:column!important}.flex-md-row-reverse{flex-direction:row-reverse!important}.flex-md-column-reverse{flex-direction:column-reverse!important}.flex-md-wrap{flex-wrap:wrap!important}.flex-md-nowrap{flex-wrap:nowrap!important}.flex-md-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-md-fill{flex:1 1 auto!important}.flex-md-grow-0{flex-grow:0!important}.flex-md-grow-1{flex-grow:1!important}.flex-md-shrink-0{flex-shrink:0!important}.flex-md-shrink-1{flex-shrink:1!important}.justify-content-md-start{justify-content:flex-start!important}.justify-content-md-end{justify-content:flex-end!important}.justify-content-md-center{justify-content:center!important}.justify-content-md-between{justify-content:space-between!important}.justify-content-md-around{justify-content:space-around!important}.align-items-md-start{align-items:flex-start!important}.align-items-md-end{align-items:flex-end!important}.align-items-md-center{align-items:center!important}.align-items-md-baseline{align-items:baseline!important}.align-items-md-stretch{align-items:stretch!important}.align-content-md-start{align-content:flex-start!important}.align-content-md-end{align-content:flex-end!important}.align-content-md-center{align-content:center!important}.align-content-md-between{align-content:space-between!important}.align-content-md-around{align-content:space-around!important}.align-content-md-stretch{align-content:stretch!important}.align-self-md-auto{align-self:auto!important}.align-self-md-start{align-self:flex-start!important}.align-self-md-end{align-self:flex-end!important}.align-self-md-center{align-self:center!important}.align-self-md-baseline{align-self:baseline!important}.align-self-md-stretch{align-self:stretch!important}}@media (min-width:992px){.flex-lg-row{flex-direction:row!important}.flex-lg-column{flex-direction:column!important}.flex-lg-row-reverse{flex-direction:row-reverse!important}.flex-lg-column-reverse{flex-direction:column-reverse!important}.flex-lg-wrap{flex-wrap:wrap!important}.flex-lg-nowrap{flex-wrap:nowrap!important}.flex-lg-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-lg-fill{flex:1 1 auto!important}.flex-lg-grow-0{flex-grow:0!important}.flex-lg-grow-1{flex-grow:1!important}.flex-lg-shrink-0{flex-shrink:0!important}.flex-lg-shrink-1{flex-shrink:1!important}.justify-content-lg-start{justify-content:flex-start!important}.justify-content-lg-end{justify-content:flex-end!important}.justify-content-lg-center{justify-content:center!important}.justify-content-lg-between{justify-content:space-between!important}.justify-content-lg-around{justify-content:space-around!important}.align-items-lg-start{align-items:flex-start!important}.align-items-lg-end{align-items:flex-end!important}.align-items-lg-center{align-items:center!important}.align-items-lg-baseline{align-items:baseline!important}.align-items-lg-stretch{align-items:stretch!important}.align-content-lg-start{align-content:flex-start!important}.align-content-lg-end{align-content:flex-end!important}.align-content-lg-center{align-content:center!important}.align-content-lg-between{align-content:space-between!important}.align-content-lg-around{align-content:space-around!important}.align-content-lg-stretch{align-content:stretch!important}.align-self-lg-auto{align-self:auto!important}.align-self-lg-start{align-self:flex-start!important}.align-self-lg-end{align-self:flex-end!important}.align-self-lg-center{align-self:center!important}.align-self-lg-baseline{align-self:baseline!important}.align-self-lg-stretch{align-self:stretch!important}}@media (min-width:1200px){.flex-xl-row{flex-direction:row!important}.flex-xl-column{flex-direction:column!important}.flex-xl-row-reverse{flex-direction:row-reverse!important}.flex-xl-column-reverse{flex-direction:column-reverse!important}.flex-xl-wrap{flex-wrap:wrap!important}.flex-xl-nowrap{flex-wrap:nowrap!important}.flex-xl-wrap-reverse{flex-wrap:wrap-reverse!important}.flex-xl-fill{flex:1 1 auto!important}.flex-xl-grow-0{flex-grow:0!important}.flex-xl-grow-1{flex-grow:1!important}.flex-xl-shrink-0{flex-shrink:0!important}.flex-xl-shrink-1{flex-shrink:1!important}.justify-content-xl-start{justify-content:flex-start!important}.justify-content-xl-end{justify-content:flex-end!important}.justify-content-xl-center{justify-content:center!important}.justify-content-xl-between{justify-content:space-between!important}.justify-content-xl-around{justify-content:space-around!important}.align-items-xl-start{align-items:flex-start!important}.align-items-xl-end{align-items:flex-end!important}.align-items-xl-center{align-items:center!important}.align-items-xl-baseline{align-items:baseline!important}.align-items-xl-stretch{align-items:stretch!important}.align-content-xl-start{align-content:flex-start!important}.align-content-xl-end{align-content:flex-end!important}.align-content-xl-center{align-content:center!important}.align-content-xl-between{align-content:space-between!important}.align-content-xl-around{align-content:space-around!important}.align-content-xl-stretch{align-content:stretch!important}.align-self-xl-auto{align-self:auto!important}.align-self-xl-start{align-self:flex-start!important}.align-self-xl-end{align-self:flex-end!important}.align-self-xl-center{align-self:center!important}.align-self-xl-baseline{align-self:baseline!important}.align-self-xl-stretch{align-self:stretch!important}}.float-left{float:left!important}.float-right{float:right!important}.float-none{float:none!important}@media (min-width:576px){.float-sm-left{float:left!important}.float-sm-right{float:right!important}.float-sm-none{float:none!important}}@media (min-width:768px){.float-md-left{float:left!important}.float-md-right{float:right!important}.float-md-none{float:none!important}}@media (min-width:992px){.float-lg-left{float:left!important}.float-lg-right{float:right!important}.float-lg-none{float:none!important}}@media (min-width:1200px){.float-xl-left{float:left!important}.float-xl-right{float:right!important}.float-xl-none{float:none!important}}.overflow-auto{overflow:auto!important}.overflow-hidden{overflow:hidden!important}.position-static{position:static!important}.position-relative{position:relative!important}.position-absolute{position:absolute!important}.position-fixed{position:fixed!important}.position-sticky{position:-webkit-sticky!important;position:sticky!important}.fixed-top{top:0}.fixed-bottom,.fixed-top{position:fixed;right:0;left:0;z-index:1030}.fixed-bottom{bottom:0}@supports ((position:-webkit-sticky) or (position:sticky)){.sticky-top{position:-webkit-sticky;position:sticky;top:0;z-index:1020}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;overflow:visible;clip:auto;white-space:normal}.shadow-sm{box-shadow:0 .125rem .25rem rgba(0,0,0,.075)!important}.shadow{box-shadow:0 .5rem 1rem rgba(0,0,0,.15)!important}.shadow-lg{box-shadow:0 1rem 3rem rgba(0,0,0,.175)!important}.shadow-none{box-shadow:none!important}.w-25{width:25%!important}.w-50{width:50%!important}.w-75{width:75%!important}.w-100{width:100%!important}.w-auto{width:auto!important}.h-25{height:25%!important}.h-50{height:50%!important}.h-75{height:75%!important}.h-100{height:100%!important}.h-auto{height:auto!important}.mw-100{max-width:100%!important}.mh-100{max-height:100%!important}.min-vw-100{min-width:100vw!important}.min-vh-100{min-height:100vh!important}.vw-100{width:100vw!important}.vh-100{height:100vh!important}.stretched-link:after{position:absolute;top:0;right:0;bottom:0;left:0;z-index:1;pointer-events:auto;content:"";background-color:transparent}.m-0{margin:0!important}.mt-0,.my-0{margin-top:0!important}.mr-0,.mx-0{margin-right:0!important}.mb-0,.my-0{margin-bottom:0!important}.ml-0,.mx-0{margin-left:0!important}.m-1{margin:.25rem!important}.mt-1,.my-1{margin-top:.25rem!important}.mr-1,.mx-1{margin-right:.25rem!important}.mb-1,.my-1{margin-bottom:.25rem!important}.ml-1,.mx-1{margin-left:.25rem!important}.m-2{margin:.5rem!important}.mt-2,.my-2{margin-top:.5rem!important}.mr-2,.mx-2{margin-right:.5rem!important}.mb-2,.my-2{margin-bottom:.5rem!important}.ml-2,.mx-2{margin-left:.5rem!important}.m-3{margin:1rem!important}.mt-3,.my-3{margin-top:1rem!important}.mr-3,.mx-3{margin-right:1rem!important}.mb-3,.my-3{margin-bottom:1rem!important}.ml-3,.mx-3{margin-left:1rem!important}.m-4{margin:1.5rem!important}.mt-4,.my-4{margin-top:1.5rem!important}.mr-4,.mx-4{margin-right:1.5rem!important}.mb-4,.my-4{margin-bottom:1.5rem!important}.ml-4,.mx-4{margin-left:1.5rem!important}.m-5{margin:3rem!important}.mt-5,.my-5{margin-top:3rem!important}.mr-5,.mx-5{margin-right:3rem!important}.mb-5,.my-5{margin-bottom:3rem!important}.ml-5,.mx-5{margin-left:3rem!important}.p-0{padding:0!important}.pt-0,.py-0{padding-top:0!important}.pr-0,.px-0{padding-right:0!important}.pb-0,.py-0{padding-bottom:0!important}.pl-0,.px-0{padding-left:0!important}.p-1{padding:.25rem!important}.pt-1,.py-1{padding-top:.25rem!important}.pr-1,.px-1{padding-right:.25rem!important}.pb-1,.py-1{padding-bottom:.25rem!important}.pl-1,.px-1{padding-left:.25rem!important}.p-2{padding:.5rem!important}.pt-2,.py-2{padding-top:.5rem!important}.pr-2,.px-2{padding-right:.5rem!important}.pb-2,.py-2{padding-bottom:.5rem!important}.pl-2,.px-2{padding-left:.5rem!important}.p-3{padding:1rem!important}.pt-3,.py-3{padding-top:1rem!important}.pr-3,.px-3{padding-right:1rem!important}.pb-3,.py-3{padding-bottom:1rem!important}.pl-3,.px-3{padding-left:1rem!important}.p-4{padding:1.5rem!important}.pt-4,.py-4{padding-top:1.5rem!important}.pr-4,.px-4{padding-right:1.5rem!important}.pb-4,.py-4{padding-bottom:1.5rem!important}.pl-4,.px-4{padding-left:1.5rem!important}.p-5{padding:3rem!important}.pt-5,.py-5{padding-top:3rem!important}.pr-5,.px-5{padding-right:3rem!important}.pb-5,.py-5{padding-bottom:3rem!important}.pl-5,.px-5{padding-left:3rem!important}.m-n1{margin:-.25rem!important}.mt-n1,.my-n1{margin-top:-.25rem!important}.mr-n1,.mx-n1{margin-right:-.25rem!important}.mb-n1,.my-n1{margin-bottom:-.25rem!important}.ml-n1,.mx-n1{margin-left:-.25rem!important}.m-n2{margin:-.5rem!important}.mt-n2,.my-n2{margin-top:-.5rem!important}.mr-n2,.mx-n2{margin-right:-.5rem!important}.mb-n2,.my-n2{margin-bottom:-.5rem!important}.ml-n2,.mx-n2{margin-left:-.5rem!important}.m-n3{margin:-1rem!important}.mt-n3,.my-n3{margin-top:-1rem!important}.mr-n3,.mx-n3{margin-right:-1rem!important}.mb-n3,.my-n3{margin-bottom:-1rem!important}.ml-n3,.mx-n3{margin-left:-1rem!important}.m-n4{margin:-1.5rem!important}.mt-n4,.my-n4{margin-top:-1.5rem!important}.mr-n4,.mx-n4{margin-right:-1.5rem!important}.mb-n4,.my-n4{margin-bottom:-1.5rem!important}.ml-n4,.mx-n4{margin-left:-1.5rem!important}.m-n5{margin:-3rem!important}.mt-n5,.my-n5{margin-top:-3rem!important}.mr-n5,.mx-n5{margin-right:-3rem!important}.mb-n5,.my-n5{margin-bottom:-3rem!important}.ml-n5,.mx-n5{margin-left:-3rem!important}.m-auto{margin:auto!important}.mt-auto,.my-auto{margin-top:auto!important}.mr-auto,.mx-auto{margin-right:auto!important}.mb-auto,.my-auto{margin-bottom:auto!important}.ml-auto,.mx-auto{margin-left:auto!important}@media (min-width:576px){.m-sm-0{margin:0!important}.mt-sm-0,.my-sm-0{margin-top:0!important}.mr-sm-0,.mx-sm-0{margin-right:0!important}.mb-sm-0,.my-sm-0{margin-bottom:0!important}.ml-sm-0,.mx-sm-0{margin-left:0!important}.m-sm-1{margin:.25rem!important}.mt-sm-1,.my-sm-1{margin-top:.25rem!important}.mr-sm-1,.mx-sm-1{margin-right:.25rem!important}.mb-sm-1,.my-sm-1{margin-bottom:.25rem!important}.ml-sm-1,.mx-sm-1{margin-left:.25rem!important}.m-sm-2{margin:.5rem!important}.mt-sm-2,.my-sm-2{margin-top:.5rem!important}.mr-sm-2,.mx-sm-2{margin-right:.5rem!important}.mb-sm-2,.my-sm-2{margin-bottom:.5rem!important}.ml-sm-2,.mx-sm-2{margin-left:.5rem!important}.m-sm-3{margin:1rem!important}.mt-sm-3,.my-sm-3{margin-top:1rem!important}.mr-sm-3,.mx-sm-3{margin-right:1rem!important}.mb-sm-3,.my-sm-3{margin-bottom:1rem!important}.ml-sm-3,.mx-sm-3{margin-left:1rem!important}.m-sm-4{margin:1.5rem!important}.mt-sm-4,.my-sm-4{margin-top:1.5rem!important}.mr-sm-4,.mx-sm-4{margin-right:1.5rem!important}.mb-sm-4,.my-sm-4{margin-bottom:1.5rem!important}.ml-sm-4,.mx-sm-4{margin-left:1.5rem!important}.m-sm-5{margin:3rem!important}.mt-sm-5,.my-sm-5{margin-top:3rem!important}.mr-sm-5,.mx-sm-5{margin-right:3rem!important}.mb-sm-5,.my-sm-5{margin-bottom:3rem!important}.ml-sm-5,.mx-sm-5{margin-left:3rem!important}.p-sm-0{padding:0!important}.pt-sm-0,.py-sm-0{padding-top:0!important}.pr-sm-0,.px-sm-0{padding-right:0!important}.pb-sm-0,.py-sm-0{padding-bottom:0!important}.pl-sm-0,.px-sm-0{padding-left:0!important}.p-sm-1{padding:.25rem!important}.pt-sm-1,.py-sm-1{padding-top:.25rem!important}.pr-sm-1,.px-sm-1{padding-right:.25rem!important}.pb-sm-1,.py-sm-1{padding-bottom:.25rem!important}.pl-sm-1,.px-sm-1{padding-left:.25rem!important}.p-sm-2{padding:.5rem!important}.pt-sm-2,.py-sm-2{padding-top:.5rem!important}.pr-sm-2,.px-sm-2{padding-right:.5rem!important}.pb-sm-2,.py-sm-2{padding-bottom:.5rem!important}.pl-sm-2,.px-sm-2{padding-left:.5rem!important}.p-sm-3{padding:1rem!important}.pt-sm-3,.py-sm-3{padding-top:1rem!important}.pr-sm-3,.px-sm-3{padding-right:1rem!important}.pb-sm-3,.py-sm-3{padding-bottom:1rem!important}.pl-sm-3,.px-sm-3{padding-left:1rem!important}.p-sm-4{padding:1.5rem!important}.pt-sm-4,.py-sm-4{padding-top:1.5rem!important}.pr-sm-4,.px-sm-4{padding-right:1.5rem!important}.pb-sm-4,.py-sm-4{padding-bottom:1.5rem!important}.pl-sm-4,.px-sm-4{padding-left:1.5rem!important}.p-sm-5{padding:3rem!important}.pt-sm-5,.py-sm-5{padding-top:3rem!important}.pr-sm-5,.px-sm-5{padding-right:3rem!important}.pb-sm-5,.py-sm-5{padding-bottom:3rem!important}.pl-sm-5,.px-sm-5{padding-left:3rem!important}.m-sm-n1{margin:-.25rem!important}.mt-sm-n1,.my-sm-n1{margin-top:-.25rem!important}.mr-sm-n1,.mx-sm-n1{margin-right:-.25rem!important}.mb-sm-n1,.my-sm-n1{margin-bottom:-.25rem!important}.ml-sm-n1,.mx-sm-n1{margin-left:-.25rem!important}.m-sm-n2{margin:-.5rem!important}.mt-sm-n2,.my-sm-n2{margin-top:-.5rem!important}.mr-sm-n2,.mx-sm-n2{margin-right:-.5rem!important}.mb-sm-n2,.my-sm-n2{margin-bottom:-.5rem!important}.ml-sm-n2,.mx-sm-n2{margin-left:-.5rem!important}.m-sm-n3{margin:-1rem!important}.mt-sm-n3,.my-sm-n3{margin-top:-1rem!important}.mr-sm-n3,.mx-sm-n3{margin-right:-1rem!important}.mb-sm-n3,.my-sm-n3{margin-bottom:-1rem!important}.ml-sm-n3,.mx-sm-n3{margin-left:-1rem!important}.m-sm-n4{margin:-1.5rem!important}.mt-sm-n4,.my-sm-n4{margin-top:-1.5rem!important}.mr-sm-n4,.mx-sm-n4{margin-right:-1.5rem!important}.mb-sm-n4,.my-sm-n4{margin-bottom:-1.5rem!important}.ml-sm-n4,.mx-sm-n4{margin-left:-1.5rem!important}.m-sm-n5{margin:-3rem!important}.mt-sm-n5,.my-sm-n5{margin-top:-3rem!important}.mr-sm-n5,.mx-sm-n5{margin-right:-3rem!important}.mb-sm-n5,.my-sm-n5{margin-bottom:-3rem!important}.ml-sm-n5,.mx-sm-n5{margin-left:-3rem!important}.m-sm-auto{margin:auto!important}.mt-sm-auto,.my-sm-auto{margin-top:auto!important}.mr-sm-auto,.mx-sm-auto{margin-right:auto!important}.mb-sm-auto,.my-sm-auto{margin-bottom:auto!important}.ml-sm-auto,.mx-sm-auto{margin-left:auto!important}}@media (min-width:768px){.m-md-0{margin:0!important}.mt-md-0,.my-md-0{margin-top:0!important}.mr-md-0,.mx-md-0{margin-right:0!important}.mb-md-0,.my-md-0{margin-bottom:0!important}.ml-md-0,.mx-md-0{margin-left:0!important}.m-md-1{margin:.25rem!important}.mt-md-1,.my-md-1{margin-top:.25rem!important}.mr-md-1,.mx-md-1{margin-right:.25rem!important}.mb-md-1,.my-md-1{margin-bottom:.25rem!important}.ml-md-1,.mx-md-1{margin-left:.25rem!important}.m-md-2{margin:.5rem!important}.mt-md-2,.my-md-2{margin-top:.5rem!important}.mr-md-2,.mx-md-2{margin-right:.5rem!important}.mb-md-2,.my-md-2{margin-bottom:.5rem!important}.ml-md-2,.mx-md-2{margin-left:.5rem!important}.m-md-3{margin:1rem!important}.mt-md-3,.my-md-3{margin-top:1rem!important}.mr-md-3,.mx-md-3{margin-right:1rem!important}.mb-md-3,.my-md-3{margin-bottom:1rem!important}.ml-md-3,.mx-md-3{margin-left:1rem!important}.m-md-4{margin:1.5rem!important}.mt-md-4,.my-md-4{margin-top:1.5rem!important}.mr-md-4,.mx-md-4{margin-right:1.5rem!important}.mb-md-4,.my-md-4{margin-bottom:1.5rem!important}.ml-md-4,.mx-md-4{margin-left:1.5rem!important}.m-md-5{margin:3rem!important}.mt-md-5,.my-md-5{margin-top:3rem!important}.mr-md-5,.mx-md-5{margin-right:3rem!important}.mb-md-5,.my-md-5{margin-bottom:3rem!important}.ml-md-5,.mx-md-5{margin-left:3rem!important}.p-md-0{padding:0!important}.pt-md-0,.py-md-0{padding-top:0!important}.pr-md-0,.px-md-0{padding-right:0!important}.pb-md-0,.py-md-0{padding-bottom:0!important}.pl-md-0,.px-md-0{padding-left:0!important}.p-md-1{padding:.25rem!important}.pt-md-1,.py-md-1{padding-top:.25rem!important}.pr-md-1,.px-md-1{padding-right:.25rem!important}.pb-md-1,.py-md-1{padding-bottom:.25rem!important}.pl-md-1,.px-md-1{padding-left:.25rem!important}.p-md-2{padding:.5rem!important}.pt-md-2,.py-md-2{padding-top:.5rem!important}.pr-md-2,.px-md-2{padding-right:.5rem!important}.pb-md-2,.py-md-2{padding-bottom:.5rem!important}.pl-md-2,.px-md-2{padding-left:.5rem!important}.p-md-3{padding:1rem!important}.pt-md-3,.py-md-3{padding-top:1rem!important}.pr-md-3,.px-md-3{padding-right:1rem!important}.pb-md-3,.py-md-3{padding-bottom:1rem!important}.pl-md-3,.px-md-3{padding-left:1rem!important}.p-md-4{padding:1.5rem!important}.pt-md-4,.py-md-4{padding-top:1.5rem!important}.pr-md-4,.px-md-4{padding-right:1.5rem!important}.pb-md-4,.py-md-4{padding-bottom:1.5rem!important}.pl-md-4,.px-md-4{padding-left:1.5rem!important}.p-md-5{padding:3rem!important}.pt-md-5,.py-md-5{padding-top:3rem!important}.pr-md-5,.px-md-5{padding-right:3rem!important}.pb-md-5,.py-md-5{padding-bottom:3rem!important}.pl-md-5,.px-md-5{padding-left:3rem!important}.m-md-n1{margin:-.25rem!important}.mt-md-n1,.my-md-n1{margin-top:-.25rem!important}.mr-md-n1,.mx-md-n1{margin-right:-.25rem!important}.mb-md-n1,.my-md-n1{margin-bottom:-.25rem!important}.ml-md-n1,.mx-md-n1{margin-left:-.25rem!important}.m-md-n2{margin:-.5rem!important}.mt-md-n2,.my-md-n2{margin-top:-.5rem!important}.mr-md-n2,.mx-md-n2{margin-right:-.5rem!important}.mb-md-n2,.my-md-n2{margin-bottom:-.5rem!important}.ml-md-n2,.mx-md-n2{margin-left:-.5rem!important}.m-md-n3{margin:-1rem!important}.mt-md-n3,.my-md-n3{margin-top:-1rem!important}.mr-md-n3,.mx-md-n3{margin-right:-1rem!important}.mb-md-n3,.my-md-n3{margin-bottom:-1rem!important}.ml-md-n3,.mx-md-n3{margin-left:-1rem!important}.m-md-n4{margin:-1.5rem!important}.mt-md-n4,.my-md-n4{margin-top:-1.5rem!important}.mr-md-n4,.mx-md-n4{margin-right:-1.5rem!important}.mb-md-n4,.my-md-n4{margin-bottom:-1.5rem!important}.ml-md-n4,.mx-md-n4{margin-left:-1.5rem!important}.m-md-n5{margin:-3rem!important}.mt-md-n5,.my-md-n5{margin-top:-3rem!important}.mr-md-n5,.mx-md-n5{margin-right:-3rem!important}.mb-md-n5,.my-md-n5{margin-bottom:-3rem!important}.ml-md-n5,.mx-md-n5{margin-left:-3rem!important}.m-md-auto{margin:auto!important}.mt-md-auto,.my-md-auto{margin-top:auto!important}.mr-md-auto,.mx-md-auto{margin-right:auto!important}.mb-md-auto,.my-md-auto{margin-bottom:auto!important}.ml-md-auto,.mx-md-auto{margin-left:auto!important}}@media (min-width:992px){.m-lg-0{margin:0!important}.mt-lg-0,.my-lg-0{margin-top:0!important}.mr-lg-0,.mx-lg-0{margin-right:0!important}.mb-lg-0,.my-lg-0{margin-bottom:0!important}.ml-lg-0,.mx-lg-0{margin-left:0!important}.m-lg-1{margin:.25rem!important}.mt-lg-1,.my-lg-1{margin-top:.25rem!important}.mr-lg-1,.mx-lg-1{margin-right:.25rem!important}.mb-lg-1,.my-lg-1{margin-bottom:.25rem!important}.ml-lg-1,.mx-lg-1{margin-left:.25rem!important}.m-lg-2{margin:.5rem!important}.mt-lg-2,.my-lg-2{margin-top:.5rem!important}.mr-lg-2,.mx-lg-2{margin-right:.5rem!important}.mb-lg-2,.my-lg-2{margin-bottom:.5rem!important}.ml-lg-2,.mx-lg-2{margin-left:.5rem!important}.m-lg-3{margin:1rem!important}.mt-lg-3,.my-lg-3{margin-top:1rem!important}.mr-lg-3,.mx-lg-3{margin-right:1rem!important}.mb-lg-3,.my-lg-3{margin-bottom:1rem!important}.ml-lg-3,.mx-lg-3{margin-left:1rem!important}.m-lg-4{margin:1.5rem!important}.mt-lg-4,.my-lg-4{margin-top:1.5rem!important}.mr-lg-4,.mx-lg-4{margin-right:1.5rem!important}.mb-lg-4,.my-lg-4{margin-bottom:1.5rem!important}.ml-lg-4,.mx-lg-4{margin-left:1.5rem!important}.m-lg-5{margin:3rem!important}.mt-lg-5,.my-lg-5{margin-top:3rem!important}.mr-lg-5,.mx-lg-5{margin-right:3rem!important}.mb-lg-5,.my-lg-5{margin-bottom:3rem!important}.ml-lg-5,.mx-lg-5{margin-left:3rem!important}.p-lg-0{padding:0!important}.pt-lg-0,.py-lg-0{padding-top:0!important}.pr-lg-0,.px-lg-0{padding-right:0!important}.pb-lg-0,.py-lg-0{padding-bottom:0!important}.pl-lg-0,.px-lg-0{padding-left:0!important}.p-lg-1{padding:.25rem!important}.pt-lg-1,.py-lg-1{padding-top:.25rem!important}.pr-lg-1,.px-lg-1{padding-right:.25rem!important}.pb-lg-1,.py-lg-1{padding-bottom:.25rem!important}.pl-lg-1,.px-lg-1{padding-left:.25rem!important}.p-lg-2{padding:.5rem!important}.pt-lg-2,.py-lg-2{padding-top:.5rem!important}.pr-lg-2,.px-lg-2{padding-right:.5rem!important}.pb-lg-2,.py-lg-2{padding-bottom:.5rem!important}.pl-lg-2,.px-lg-2{padding-left:.5rem!important}.p-lg-3{padding:1rem!important}.pt-lg-3,.py-lg-3{padding-top:1rem!important}.pr-lg-3,.px-lg-3{padding-right:1rem!important}.pb-lg-3,.py-lg-3{padding-bottom:1rem!important}.pl-lg-3,.px-lg-3{padding-left:1rem!important}.p-lg-4{padding:1.5rem!important}.pt-lg-4,.py-lg-4{padding-top:1.5rem!important}.pr-lg-4,.px-lg-4{padding-right:1.5rem!important}.pb-lg-4,.py-lg-4{padding-bottom:1.5rem!important}.pl-lg-4,.px-lg-4{padding-left:1.5rem!important}.p-lg-5{padding:3rem!important}.pt-lg-5,.py-lg-5{padding-top:3rem!important}.pr-lg-5,.px-lg-5{padding-right:3rem!important}.pb-lg-5,.py-lg-5{padding-bottom:3rem!important}.pl-lg-5,.px-lg-5{padding-left:3rem!important}.m-lg-n1{margin:-.25rem!important}.mt-lg-n1,.my-lg-n1{margin-top:-.25rem!important}.mr-lg-n1,.mx-lg-n1{margin-right:-.25rem!important}.mb-lg-n1,.my-lg-n1{margin-bottom:-.25rem!important}.ml-lg-n1,.mx-lg-n1{margin-left:-.25rem!important}.m-lg-n2{margin:-.5rem!important}.mt-lg-n2,.my-lg-n2{margin-top:-.5rem!important}.mr-lg-n2,.mx-lg-n2{margin-right:-.5rem!important}.mb-lg-n2,.my-lg-n2{margin-bottom:-.5rem!important}.ml-lg-n2,.mx-lg-n2{margin-left:-.5rem!important}.m-lg-n3{margin:-1rem!important}.mt-lg-n3,.my-lg-n3{margin-top:-1rem!important}.mr-lg-n3,.mx-lg-n3{margin-right:-1rem!important}.mb-lg-n3,.my-lg-n3{margin-bottom:-1rem!important}.ml-lg-n3,.mx-lg-n3{margin-left:-1rem!important}.m-lg-n4{margin:-1.5rem!important}.mt-lg-n4,.my-lg-n4{margin-top:-1.5rem!important}.mr-lg-n4,.mx-lg-n4{margin-right:-1.5rem!important}.mb-lg-n4,.my-lg-n4{margin-bottom:-1.5rem!important}.ml-lg-n4,.mx-lg-n4{margin-left:-1.5rem!important}.m-lg-n5{margin:-3rem!important}.mt-lg-n5,.my-lg-n5{margin-top:-3rem!important}.mr-lg-n5,.mx-lg-n5{margin-right:-3rem!important}.mb-lg-n5,.my-lg-n5{margin-bottom:-3rem!important}.ml-lg-n5,.mx-lg-n5{margin-left:-3rem!important}.m-lg-auto{margin:auto!important}.mt-lg-auto,.my-lg-auto{margin-top:auto!important}.mr-lg-auto,.mx-lg-auto{margin-right:auto!important}.mb-lg-auto,.my-lg-auto{margin-bottom:auto!important}.ml-lg-auto,.mx-lg-auto{margin-left:auto!important}}@media (min-width:1200px){.m-xl-0{margin:0!important}.mt-xl-0,.my-xl-0{margin-top:0!important}.mr-xl-0,.mx-xl-0{margin-right:0!important}.mb-xl-0,.my-xl-0{margin-bottom:0!important}.ml-xl-0,.mx-xl-0{margin-left:0!important}.m-xl-1{margin:.25rem!important}.mt-xl-1,.my-xl-1{margin-top:.25rem!important}.mr-xl-1,.mx-xl-1{margin-right:.25rem!important}.mb-xl-1,.my-xl-1{margin-bottom:.25rem!important}.ml-xl-1,.mx-xl-1{margin-left:.25rem!important}.m-xl-2{margin:.5rem!important}.mt-xl-2,.my-xl-2{margin-top:.5rem!important}.mr-xl-2,.mx-xl-2{margin-right:.5rem!important}.mb-xl-2,.my-xl-2{margin-bottom:.5rem!important}.ml-xl-2,.mx-xl-2{margin-left:.5rem!important}.m-xl-3{margin:1rem!important}.mt-xl-3,.my-xl-3{margin-top:1rem!important}.mr-xl-3,.mx-xl-3{margin-right:1rem!important}.mb-xl-3,.my-xl-3{margin-bottom:1rem!important}.ml-xl-3,.mx-xl-3{margin-left:1rem!important}.m-xl-4{margin:1.5rem!important}.mt-xl-4,.my-xl-4{margin-top:1.5rem!important}.mr-xl-4,.mx-xl-4{margin-right:1.5rem!important}.mb-xl-4,.my-xl-4{margin-bottom:1.5rem!important}.ml-xl-4,.mx-xl-4{margin-left:1.5rem!important}.m-xl-5{margin:3rem!important}.mt-xl-5,.my-xl-5{margin-top:3rem!important}.mr-xl-5,.mx-xl-5{margin-right:3rem!important}.mb-xl-5,.my-xl-5{margin-bottom:3rem!important}.ml-xl-5,.mx-xl-5{margin-left:3rem!important}.p-xl-0{padding:0!important}.pt-xl-0,.py-xl-0{padding-top:0!important}.pr-xl-0,.px-xl-0{padding-right:0!important}.pb-xl-0,.py-xl-0{padding-bottom:0!important}.pl-xl-0,.px-xl-0{padding-left:0!important}.p-xl-1{padding:.25rem!important}.pt-xl-1,.py-xl-1{padding-top:.25rem!important}.pr-xl-1,.px-xl-1{padding-right:.25rem!important}.pb-xl-1,.py-xl-1{padding-bottom:.25rem!important}.pl-xl-1,.px-xl-1{padding-left:.25rem!important}.p-xl-2{padding:.5rem!important}.pt-xl-2,.py-xl-2{padding-top:.5rem!important}.pr-xl-2,.px-xl-2{padding-right:.5rem!important}.pb-xl-2,.py-xl-2{padding-bottom:.5rem!important}.pl-xl-2,.px-xl-2{padding-left:.5rem!important}.p-xl-3{padding:1rem!important}.pt-xl-3,.py-xl-3{padding-top:1rem!important}.pr-xl-3,.px-xl-3{padding-right:1rem!important}.pb-xl-3,.py-xl-3{padding-bottom:1rem!important}.pl-xl-3,.px-xl-3{padding-left:1rem!important}.p-xl-4{padding:1.5rem!important}.pt-xl-4,.py-xl-4{padding-top:1.5rem!important}.pr-xl-4,.px-xl-4{padding-right:1.5rem!important}.pb-xl-4,.py-xl-4{padding-bottom:1.5rem!important}.pl-xl-4,.px-xl-4{padding-left:1.5rem!important}.p-xl-5{padding:3rem!important}.pt-xl-5,.py-xl-5{padding-top:3rem!important}.pr-xl-5,.px-xl-5{padding-right:3rem!important}.pb-xl-5,.py-xl-5{padding-bottom:3rem!important}.pl-xl-5,.px-xl-5{padding-left:3rem!important}.m-xl-n1{margin:-.25rem!important}.mt-xl-n1,.my-xl-n1{margin-top:-.25rem!important}.mr-xl-n1,.mx-xl-n1{margin-right:-.25rem!important}.mb-xl-n1,.my-xl-n1{margin-bottom:-.25rem!important}.ml-xl-n1,.mx-xl-n1{margin-left:-.25rem!important}.m-xl-n2{margin:-.5rem!important}.mt-xl-n2,.my-xl-n2{margin-top:-.5rem!important}.mr-xl-n2,.mx-xl-n2{margin-right:-.5rem!important}.mb-xl-n2,.my-xl-n2{margin-bottom:-.5rem!important}.ml-xl-n2,.mx-xl-n2{margin-left:-.5rem!important}.m-xl-n3{margin:-1rem!important}.mt-xl-n3,.my-xl-n3{margin-top:-1rem!important}.mr-xl-n3,.mx-xl-n3{margin-right:-1rem!important}.mb-xl-n3,.my-xl-n3{margin-bottom:-1rem!important}.ml-xl-n3,.mx-xl-n3{margin-left:-1rem!important}.m-xl-n4{margin:-1.5rem!important}.mt-xl-n4,.my-xl-n4{margin-top:-1.5rem!important}.mr-xl-n4,.mx-xl-n4{margin-right:-1.5rem!important}.mb-xl-n4,.my-xl-n4{margin-bottom:-1.5rem!important}.ml-xl-n4,.mx-xl-n4{margin-left:-1.5rem!important}.m-xl-n5{margin:-3rem!important}.mt-xl-n5,.my-xl-n5{margin-top:-3rem!important}.mr-xl-n5,.mx-xl-n5{margin-right:-3rem!important}.mb-xl-n5,.my-xl-n5{margin-bottom:-3rem!important}.ml-xl-n5,.mx-xl-n5{margin-left:-3rem!important}.m-xl-auto{margin:auto!important}.mt-xl-auto,.my-xl-auto{margin-top:auto!important}.mr-xl-auto,.mx-xl-auto{margin-right:auto!important}.mb-xl-auto,.my-xl-auto{margin-bottom:auto!important}.ml-xl-auto,.mx-xl-auto{margin-left:auto!important}}.text-monospace{font-family:SFMono-Regular,Menlo,Monaco,Consolas,Liberation Mono,Courier New,monospace!important}.text-justify{text-align:justify!important}.text-wrap{white-space:normal!important}.text-nowrap{white-space:nowrap!important}.text-truncate{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.text-left{text-align:left!important}.text-right{text-align:right!important}.text-center{text-align:center!important}@media (min-width:576px){.text-sm-left{text-align:left!important}.text-sm-right{text-align:right!important}.text-sm-center{text-align:center!important}}@media (min-width:768px){.text-md-left{text-align:left!important}.text-md-right{text-align:right!important}.text-md-center{text-align:center!important}}@media (min-width:992px){.text-lg-left{text-align:left!important}.text-lg-right{text-align:right!important}.text-lg-center{text-align:center!important}}@media (min-width:1200px){.text-xl-left{text-align:left!important}.text-xl-right{text-align:right!important}.text-xl-center{text-align:center!important}}.text-lowercase{text-transform:lowercase!important}.text-uppercase{text-transform:uppercase!important}.text-capitalize{text-transform:capitalize!important}.font-weight-light{font-weight:300!important}.font-weight-lighter{font-weight:lighter!important}.font-weight-normal{font-weight:400!important}.font-weight-bold{font-weight:700!important}.font-weight-bolder{font-weight:bolder!important}.font-italic{font-style:italic!important}.text-primary{color:#007bff!important}a.text-primary:focus,a.text-primary:hover{color:#0056b3!important}.text-secondary{color:#6c757d!important}a.text-secondary:focus,a.text-secondary:hover{color:#494f54!important}.text-success{color:#28a745!important}a.text-success:focus,a.text-success:hover{color:#19692c!important}.text-info{color:#17a2b8!important}a.text-info:focus,a.text-info:hover{color:#0f6674!important}.text-warning{color:#ffc107!important}a.text-warning:focus,a.text-warning:hover{color:#ba8b00!important}.text-danger{color:#dc3545!important}a.text-danger:focus,a.text-danger:hover{color:#a71d2a!important}.text-light{color:#f8f9fa!important}a.text-light:focus,a.text-light:hover{color:#cbd3da!important}.text-dark{color:#343a40!important}a.text-dark:focus,a.text-dark:hover{color:#121416!important}.text-body{color:#212529!important}.text-muted{color:#6c757d!important}.text-black-50{color:rgba(0,0,0,.5)!important}.text-white-50{color:hsla(0,0%,100%,.5)!important}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.text-decoration-none{text-decoration:none!important}.text-break{word-break:break-word!important;overflow-wrap:break-word!important}.text-reset{color:inherit!important}.visible{visibility:visible!important}.invisible{visibility:hidden!important}@media print{*,:after,:before{text-shadow:none!important;box-shadow:none!important}a:not(.btn){text-decoration:underline}abbr[title]:after{content:" (" attr(title) ")"}pre{white-space:pre-wrap!important}blockquote,pre{border:1px solid #adb5bd;page-break-inside:avoid}thead{display:table-header-group}img,tr{page-break-inside:avoid}h2,h3,p{orphans:3;widows:3}h2,h3{page-break-after:avoid}@page{size:a3}.container,body{min-width:992px!important}.navbar{display:none}.badge{border:1px solid #000}.table{border-collapse:collapse!important}.table td,.table th{background-color:#fff!important}.table-bordered td,.table-bordered th{border:1px solid #dee2e6!important}.table-dark{color:inherit}.table-dark tbody+tbody,.table-dark td,.table-dark th,.table-dark thead th{border-color:#dee2e6}.table .thead-dark th{color:inherit;border-color:#dee2e6}}html.scroll-smooth{scroll-behavior:smooth}.wrapper,body,html{min-height:100%}.wrapper{position:relative}.wrapper .content-wrapper{min-height:calc(100vh - 3.5rem - 1px - 3.5rem - 1px)}.layout-boxed .wrapper{box-shadow:0 0 10 rgba(0,0,0,.3)}.layout-boxed .wrapper,.layout-boxed .wrapper:before{margin:0 auto;max-width:1250px}.layout-boxed .wrapper .main-sidebar{left:inherit}@supports not (-webkit-touch-callout:none){.layout-fixed .wrapper .sidebar{height:calc(100vh - 3.5rem - 1px)}.layout-fixed.text-sm .wrapper .sidebar{height:calc(100vh - 2.93725rem - 1px)}}.layout-navbar-fixed.layout-fixed .wrapper .main-header.text-sm~.control-sidebar{top:calc(2.93725rem + 1px)}.layout-navbar-fixed.layout-fixed .wrapper .brand-link.text-sm~.sidebar{margin-top:calc(2.93725rem + 1px)}.layout-navbar-fixed.sidebar-mini-md.sidebar-collapse .wrapper .brand-link,.layout-navbar-fixed.sidebar-mini.sidebar-collapse .wrapper .brand-link{height:calc(3.5rem + 1px);width:4.6rem}.layout-navbar-fixed.sidebar-mini-md.sidebar-collapse.text-sm .wrapper .brand-link,.layout-navbar-fixed.sidebar-mini-md.sidebar-collapse .wrapper .brand-link.text-sm,.layout-navbar-fixed.sidebar-mini.sidebar-collapse.text-sm .wrapper .brand-link,.layout-navbar-fixed.sidebar-mini.sidebar-collapse .wrapper .brand-link.text-sm{height:calc(2.93725rem + 1px)}.layout-navbar-fixed .wrapper .main-sidebar:hover .brand-link{transition:width .3s ease-in-out;width:250px}.layout-navbar-fixed .wrapper .main-header.text-sm~.content-wrapper{margin-top:calc(2.93725rem + 1px)}.layout-navbar-fixed .wrapper .main-header{z-index:1033}.layout-navbar-fixed.layout-fixed .wrapper .control-sidebar{top:calc(3.5rem + 1px)}.layout-navbar-fixed.layout-fixed .wrapper .main-header.text-sm~.control-sidebar,.text-sm .layout-navbar-fixed.layout-fixed .wrapper .main-header~.control-sidebar{top:calc(2.93725rem + 1px)}.layout-navbar-fixed.layout-fixed .wrapper .sidebar{margin-top:calc(3.5rem + 1px)}.layout-navbar-fixed.layout-fixed .wrapper .brand-link.text-sm~.sidebar,.text-sm .layout-navbar-fixed.layout-fixed .wrapper .brand-link~.sidebar{margin-top:calc(2.93725rem + 1px)}.layout-navbar-fixed.layout-fixed.text-sm .wrapper .control-sidebar{top:calc(2.93725rem + 1px)}.layout-navbar-fixed.layout-fixed.text-sm .wrapper .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-navbar-fixed .wrapper .control-sidebar{top:0}.layout-navbar-fixed .wrapper a.anchor{display:block;position:relative;top:calc((4.5rem + 1px)/-1)}.layout-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(3.5rem + 1px);transition:width .3s ease-in-out;width:4.6rem}.layout-navbar-fixed .wrapper.sidebar-collapse .brand-link.text-sm,.text-sm .layout-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(2.93725rem + 1px)}.layout-navbar-fixed .wrapper .brand-link,.layout-navbar-fixed .wrapper.sidebar-collapse .main-sidebar:hover .brand-link{transition:width .3s ease-in-out;width:250px}.layout-navbar-fixed .wrapper .brand-link{overflow:hidden;position:fixed;top:0;z-index:1035}.layout-navbar-fixed .wrapper .sidebar-dark-primary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-primary .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .sidebar-dark-secondary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-secondary .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .sidebar-dark-success .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-success .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .sidebar-dark-info .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-info .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .sidebar-dark-warning .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-warning .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .sidebar-dark-danger .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-danger .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .sidebar-dark-light .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-light .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .sidebar-dark-dark .brand-link:not([class*=navbar]){background-color:#343a40}.layout-navbar-fixed .wrapper .sidebar-light-dark .brand-link:not([class*=navbar]){background-color:#fff}.layout-navbar-fixed .wrapper .content-wrapper{margin-top:calc(3.5rem + 1px)}.layout-navbar-fixed .wrapper .main-header.text-sm~.content-wrapper,.text-sm .layout-navbar-fixed .wrapper .main-header~.content-wrapper{margin-top:calc(2.93725rem + 1px)}.layout-navbar-fixed .wrapper .main-header{left:0;position:fixed;right:0;top:0;z-index:1037}.layout-navbar-fixed.text-sm .wrapper .content-wrapper{margin-top:calc(2.93725rem + 1px)}body:not(.layout-fixed).layout-navbar-fixed.text-sm .wrapper .main-sidebar{margin-top:calc((2.93725rem + 1px)/-1)}body:not(.layout-fixed).layout-navbar-fixed.text-sm .wrapper .main-sidebar .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-navbar-not-fixed .wrapper .brand-link{position:static}.layout-navbar-not-fixed .wrapper .content-wrapper,.layout-navbar-not-fixed .wrapper .sidebar{margin-top:0}.layout-navbar-not-fixed .wrapper .main-header{position:static}.layout-navbar-not-fixed.layout-fixed .wrapper .sidebar{margin-top:0}@media (min-width:576px){.layout-sm-navbar-fixed.layout-fixed .wrapper .control-sidebar{top:calc(3.5rem + 1px)}.layout-sm-navbar-fixed.layout-fixed .wrapper .main-header.text-sm~.control-sidebar,.text-sm .layout-sm-navbar-fixed.layout-fixed .wrapper .main-header~.control-sidebar{top:calc(2.93725rem + 1px)}.layout-sm-navbar-fixed.layout-fixed .wrapper .sidebar{margin-top:calc(3.5rem + 1px)}.layout-sm-navbar-fixed.layout-fixed .wrapper .brand-link.text-sm~.sidebar,.text-sm .layout-sm-navbar-fixed.layout-fixed .wrapper .brand-link~.sidebar{margin-top:calc(2.93725rem + 1px)}.layout-sm-navbar-fixed.layout-fixed.text-sm .wrapper .control-sidebar{top:calc(2.93725rem + 1px)}.layout-sm-navbar-fixed.layout-fixed.text-sm .wrapper .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-sm-navbar-fixed .wrapper .control-sidebar{top:0}.layout-sm-navbar-fixed .wrapper a.anchor{display:block;position:relative;top:calc((4.5rem + 1px)/-1)}.layout-sm-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(3.5rem + 1px);transition:width .3s ease-in-out;width:4.6rem}.layout-sm-navbar-fixed .wrapper.sidebar-collapse .brand-link.text-sm,.text-sm .layout-sm-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(2.93725rem + 1px)}.layout-sm-navbar-fixed .wrapper.sidebar-collapse .main-sidebar:hover .brand-link{transition:width .3s ease-in-out;width:250px}.layout-sm-navbar-fixed .wrapper .brand-link{overflow:hidden;position:fixed;top:0;transition:width .3s ease-in-out;width:250px;z-index:1035}.layout-sm-navbar-fixed .wrapper .sidebar-dark-primary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-primary .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .sidebar-dark-secondary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-secondary .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .sidebar-dark-success .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-success .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .sidebar-dark-info .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-info .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .sidebar-dark-warning .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-warning .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .sidebar-dark-danger .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-danger .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .sidebar-dark-light .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-light .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .sidebar-dark-dark .brand-link:not([class*=navbar]){background-color:#343a40}.layout-sm-navbar-fixed .wrapper .sidebar-light-dark .brand-link:not([class*=navbar]){background-color:#fff}.layout-sm-navbar-fixed .wrapper .content-wrapper{margin-top:calc(3.5rem + 1px)}.layout-sm-navbar-fixed .wrapper .main-header.text-sm~.content-wrapper,.text-sm .layout-sm-navbar-fixed .wrapper .main-header~.content-wrapper{margin-top:calc(2.93725rem + 1px)}.layout-sm-navbar-fixed .wrapper .main-header{left:0;position:fixed;right:0;top:0;z-index:1037}.layout-sm-navbar-fixed.text-sm .wrapper .content-wrapper{margin-top:calc(2.93725rem + 1px)}body:not(.layout-fixed).layout-sm-navbar-fixed.text-sm .wrapper .main-sidebar{margin-top:calc((2.93725rem + 1px)/-1)}body:not(.layout-fixed).layout-sm-navbar-fixed.text-sm .wrapper .main-sidebar .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-sm-navbar-not-fixed .wrapper .brand-link{position:static}.layout-sm-navbar-not-fixed .wrapper .content-wrapper,.layout-sm-navbar-not-fixed .wrapper .sidebar{margin-top:0}.layout-sm-navbar-not-fixed .wrapper .main-header{position:static}.layout-sm-navbar-not-fixed.layout-fixed .wrapper .sidebar{margin-top:0}}@media (min-width:768px){.layout-md-navbar-fixed.layout-fixed .wrapper .control-sidebar{top:calc(3.5rem + 1px)}.layout-md-navbar-fixed.layout-fixed .wrapper .main-header.text-sm~.control-sidebar,.text-sm .layout-md-navbar-fixed.layout-fixed .wrapper .main-header~.control-sidebar{top:calc(2.93725rem + 1px)}.layout-md-navbar-fixed.layout-fixed .wrapper .sidebar{margin-top:calc(3.5rem + 1px)}.layout-md-navbar-fixed.layout-fixed .wrapper .brand-link.text-sm~.sidebar,.text-sm .layout-md-navbar-fixed.layout-fixed .wrapper .brand-link~.sidebar{margin-top:calc(2.93725rem + 1px)}.layout-md-navbar-fixed.layout-fixed.text-sm .wrapper .control-sidebar{top:calc(2.93725rem + 1px)}.layout-md-navbar-fixed.layout-fixed.text-sm .wrapper .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-md-navbar-fixed .wrapper .control-sidebar{top:0}.layout-md-navbar-fixed .wrapper a.anchor{display:block;position:relative;top:calc((4.5rem + 1px)/-1)}.layout-md-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(3.5rem + 1px);transition:width .3s ease-in-out;width:4.6rem}.layout-md-navbar-fixed .wrapper.sidebar-collapse .brand-link.text-sm,.text-sm .layout-md-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(2.93725rem + 1px)}.layout-md-navbar-fixed .wrapper.sidebar-collapse .main-sidebar:hover .brand-link{transition:width .3s ease-in-out;width:250px}.layout-md-navbar-fixed .wrapper .brand-link{overflow:hidden;position:fixed;top:0;transition:width .3s ease-in-out;width:250px;z-index:1035}.layout-md-navbar-fixed .wrapper .sidebar-dark-primary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-primary .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .sidebar-dark-secondary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-secondary .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .sidebar-dark-success .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-success .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .sidebar-dark-info .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-info .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .sidebar-dark-warning .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-warning .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .sidebar-dark-danger .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-danger .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .sidebar-dark-light .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-light .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .sidebar-dark-dark .brand-link:not([class*=navbar]){background-color:#343a40}.layout-md-navbar-fixed .wrapper .sidebar-light-dark .brand-link:not([class*=navbar]){background-color:#fff}.layout-md-navbar-fixed .wrapper .content-wrapper{margin-top:calc(3.5rem + 1px)}.layout-md-navbar-fixed .wrapper .main-header.text-sm~.content-wrapper,.text-sm .layout-md-navbar-fixed .wrapper .main-header~.content-wrapper{margin-top:calc(2.93725rem + 1px)}.layout-md-navbar-fixed .wrapper .main-header{left:0;position:fixed;right:0;top:0;z-index:1037}.layout-md-navbar-fixed.text-sm .wrapper .content-wrapper{margin-top:calc(2.93725rem + 1px)}body:not(.layout-fixed).layout-md-navbar-fixed.text-sm .wrapper .main-sidebar{margin-top:calc((2.93725rem + 1px)/-1)}body:not(.layout-fixed).layout-md-navbar-fixed.text-sm .wrapper .main-sidebar .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-md-navbar-not-fixed .wrapper .brand-link{position:static}.layout-md-navbar-not-fixed .wrapper .content-wrapper,.layout-md-navbar-not-fixed .wrapper .sidebar{margin-top:0}.layout-md-navbar-not-fixed .wrapper .main-header{position:static}.layout-md-navbar-not-fixed.layout-fixed .wrapper .sidebar{margin-top:0}}@media (min-width:992px){.layout-lg-navbar-fixed.layout-fixed .wrapper .control-sidebar{top:calc(3.5rem + 1px)}.layout-lg-navbar-fixed.layout-fixed .wrapper .main-header.text-sm~.control-sidebar,.text-sm .layout-lg-navbar-fixed.layout-fixed .wrapper .main-header~.control-sidebar{top:calc(2.93725rem + 1px)}.layout-lg-navbar-fixed.layout-fixed .wrapper .sidebar{margin-top:calc(3.5rem + 1px)}.layout-lg-navbar-fixed.layout-fixed .wrapper .brand-link.text-sm~.sidebar,.text-sm .layout-lg-navbar-fixed.layout-fixed .wrapper .brand-link~.sidebar{margin-top:calc(2.93725rem + 1px)}.layout-lg-navbar-fixed.layout-fixed.text-sm .wrapper .control-sidebar{top:calc(2.93725rem + 1px)}.layout-lg-navbar-fixed.layout-fixed.text-sm .wrapper .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-lg-navbar-fixed .wrapper .control-sidebar{top:0}.layout-lg-navbar-fixed .wrapper a.anchor{display:block;position:relative;top:calc((4.5rem + 1px)/-1)}.layout-lg-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(3.5rem + 1px);transition:width .3s ease-in-out;width:4.6rem}.layout-lg-navbar-fixed .wrapper.sidebar-collapse .brand-link.text-sm,.text-sm .layout-lg-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(2.93725rem + 1px)}.layout-lg-navbar-fixed .wrapper.sidebar-collapse .main-sidebar:hover .brand-link{transition:width .3s ease-in-out;width:250px}.layout-lg-navbar-fixed .wrapper .brand-link{overflow:hidden;position:fixed;top:0;transition:width .3s ease-in-out;width:250px;z-index:1035}.layout-lg-navbar-fixed .wrapper .sidebar-dark-primary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-primary .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .sidebar-dark-secondary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-secondary .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .sidebar-dark-success .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-success .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .sidebar-dark-info .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-info .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .sidebar-dark-warning .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-warning .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .sidebar-dark-danger .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-danger .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .sidebar-dark-light .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-light .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .sidebar-dark-dark .brand-link:not([class*=navbar]){background-color:#343a40}.layout-lg-navbar-fixed .wrapper .sidebar-light-dark .brand-link:not([class*=navbar]){background-color:#fff}.layout-lg-navbar-fixed .wrapper .content-wrapper{margin-top:calc(3.5rem + 1px)}.layout-lg-navbar-fixed .wrapper .main-header.text-sm~.content-wrapper,.text-sm .layout-lg-navbar-fixed .wrapper .main-header~.content-wrapper{margin-top:calc(2.93725rem + 1px)}.layout-lg-navbar-fixed .wrapper .main-header{left:0;position:fixed;right:0;top:0;z-index:1037}.layout-lg-navbar-fixed.text-sm .wrapper .content-wrapper{margin-top:calc(2.93725rem + 1px)}body:not(.layout-fixed).layout-lg-navbar-fixed.text-sm .wrapper .main-sidebar{margin-top:calc((2.93725rem + 1px)/-1)}body:not(.layout-fixed).layout-lg-navbar-fixed.text-sm .wrapper .main-sidebar .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-lg-navbar-not-fixed .wrapper .brand-link{position:static}.layout-lg-navbar-not-fixed .wrapper .content-wrapper,.layout-lg-navbar-not-fixed .wrapper .sidebar{margin-top:0}.layout-lg-navbar-not-fixed .wrapper .main-header{position:static}.layout-lg-navbar-not-fixed.layout-fixed .wrapper .sidebar{margin-top:0}}@media (min-width:1200px){.layout-xl-navbar-fixed.layout-fixed .wrapper .control-sidebar{top:calc(3.5rem + 1px)}.layout-xl-navbar-fixed.layout-fixed .wrapper .main-header.text-sm~.control-sidebar,.text-sm .layout-xl-navbar-fixed.layout-fixed .wrapper .main-header~.control-sidebar{top:calc(2.93725rem + 1px)}.layout-xl-navbar-fixed.layout-fixed .wrapper .sidebar{margin-top:calc(3.5rem + 1px)}.layout-xl-navbar-fixed.layout-fixed .wrapper .brand-link.text-sm~.sidebar,.text-sm .layout-xl-navbar-fixed.layout-fixed .wrapper .brand-link~.sidebar{margin-top:calc(2.93725rem + 1px)}.layout-xl-navbar-fixed.layout-fixed.text-sm .wrapper .control-sidebar{top:calc(2.93725rem + 1px)}.layout-xl-navbar-fixed.layout-fixed.text-sm .wrapper .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-xl-navbar-fixed .wrapper .control-sidebar{top:0}.layout-xl-navbar-fixed .wrapper a.anchor{display:block;position:relative;top:calc((4.5rem + 1px)/-1)}.layout-xl-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(3.5rem + 1px);transition:width .3s ease-in-out;width:4.6rem}.layout-xl-navbar-fixed .wrapper.sidebar-collapse .brand-link.text-sm,.text-sm .layout-xl-navbar-fixed .wrapper.sidebar-collapse .brand-link{height:calc(2.93725rem + 1px)}.layout-xl-navbar-fixed .wrapper.sidebar-collapse .main-sidebar:hover .brand-link{transition:width .3s ease-in-out;width:250px}.layout-xl-navbar-fixed .wrapper .brand-link{overflow:hidden;position:fixed;top:0;transition:width .3s ease-in-out;width:250px;z-index:1035}.layout-xl-navbar-fixed .wrapper .sidebar-dark-primary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-primary .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .sidebar-dark-secondary .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-secondary .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .sidebar-dark-success .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-success .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .sidebar-dark-info .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-info .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .sidebar-dark-warning .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-warning .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .sidebar-dark-danger .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-danger .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .sidebar-dark-light .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-light .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .sidebar-dark-dark .brand-link:not([class*=navbar]){background-color:#343a40}.layout-xl-navbar-fixed .wrapper .sidebar-light-dark .brand-link:not([class*=navbar]){background-color:#fff}.layout-xl-navbar-fixed .wrapper .content-wrapper{margin-top:calc(3.5rem + 1px)}.layout-xl-navbar-fixed .wrapper .main-header.text-sm~.content-wrapper,.text-sm .layout-xl-navbar-fixed .wrapper .main-header~.content-wrapper{margin-top:calc(2.93725rem + 1px)}.layout-xl-navbar-fixed .wrapper .main-header{left:0;position:fixed;right:0;top:0;z-index:1037}.layout-xl-navbar-fixed.text-sm .wrapper .content-wrapper{margin-top:calc(2.93725rem + 1px)}body:not(.layout-fixed).layout-xl-navbar-fixed.text-sm .wrapper .main-sidebar{margin-top:calc((2.93725rem + 1px)/-1)}body:not(.layout-fixed).layout-xl-navbar-fixed.text-sm .wrapper .main-sidebar .sidebar{margin-top:calc(2.93725rem + 1px)}.layout-xl-navbar-not-fixed .wrapper .brand-link{position:static}.layout-xl-navbar-not-fixed .wrapper .content-wrapper,.layout-xl-navbar-not-fixed .wrapper .sidebar{margin-top:0}.layout-xl-navbar-not-fixed .wrapper .main-header{position:static}.layout-xl-navbar-not-fixed.layout-fixed .wrapper .sidebar{margin-top:0}}.layout-footer-not-fixed .wrapper .content-wrapper{margin-bottom:0}.layout-footer-fixed .wrapper .control-sidebar{bottom:0}.layout-footer-fixed .wrapper .main-footer{bottom:0;left:0;position:fixed;right:0;z-index:1032}.layout-footer-fixed .wrapper .content-wrapper{padding-bottom:calc(3.5rem + 1px)}.layout-footer-not-fixed .wrapper .main-footer{position:static}@media (min-width:576px){.layout-sm-footer-fixed .wrapper .control-sidebar{bottom:0}.layout-sm-footer-fixed .wrapper .main-footer{bottom:0;left:0;position:fixed;right:0;z-index:1032}.layout-sm-footer-fixed .wrapper .content-wrapper{padding-bottom:calc(3.5rem + 1px)}.layout-sm-footer-not-fixed .wrapper .main-footer{position:static}}@media (min-width:768px){.layout-md-footer-fixed .wrapper .control-sidebar{bottom:0}.layout-md-footer-fixed .wrapper .main-footer{bottom:0;left:0;position:fixed;right:0;z-index:1032}.layout-md-footer-fixed .wrapper .content-wrapper{padding-bottom:calc(3.5rem + 1px)}.layout-md-footer-not-fixed .wrapper .main-footer{position:static}}@media (min-width:992px){.layout-lg-footer-fixed .wrapper .control-sidebar{bottom:0}.layout-lg-footer-fixed .wrapper .main-footer{bottom:0;left:0;position:fixed;right:0;z-index:1032}.layout-lg-footer-fixed .wrapper .content-wrapper{padding-bottom:calc(3.5rem + 1px)}.layout-lg-footer-not-fixed .wrapper .main-footer{position:static}}@media (min-width:1200px){.layout-xl-footer-fixed .wrapper .control-sidebar{bottom:0}.layout-xl-footer-fixed .wrapper .main-footer{bottom:0;left:0;position:fixed;right:0;z-index:1032}.layout-xl-footer-fixed .wrapper .content-wrapper{padding-bottom:calc(3.5rem + 1px)}.layout-xl-footer-not-fixed .wrapper .main-footer{position:static}}.layout-top-nav .wrapper{margin-left:0}.layout-top-nav .wrapper .main-header .brand-image{margin-top:-.5rem;margin-right:.2rem;height:33px}.layout-top-nav .wrapper .main-sidebar{bottom:inherit;height:inherit}.layout-top-nav .wrapper .content-wrapper,.layout-top-nav .wrapper .main-footer,.layout-top-nav .wrapper .main-header,body.sidebar-collapse:not(.sidebar-mini-md):not(.sidebar-mini) .content-wrapper,body.sidebar-collapse:not(.sidebar-mini-md):not(.sidebar-mini) .content-wrapper:before,body.sidebar-collapse:not(.sidebar-mini-md):not(.sidebar-mini) .main-footer,body.sidebar-collapse:not(.sidebar-mini-md):not(.sidebar-mini) .main-footer:before,body.sidebar-collapse:not(.sidebar-mini-md):not(.sidebar-mini) .main-header,body.sidebar-collapse:not(.sidebar-mini-md):not(.sidebar-mini) .main-header:before{margin-left:0}@media (min-width:768px){body:not(.sidebar-mini-md) .content-wrapper,body:not(.sidebar-mini-md) .main-footer,body:not(.sidebar-mini-md) .main-header{transition:margin-left .3s ease-in-out;margin-left:250px}}@media (min-width:768px) and (prefers-reduced-motion:reduce){body:not(.sidebar-mini-md) .content-wrapper,body:not(.sidebar-mini-md) .main-footer,body:not(.sidebar-mini-md) .main-header{transition:none}}@media (min-width:768px){.sidebar-collapse body:not(.sidebar-mini-md) .content-wrapper,.sidebar-collapse body:not(.sidebar-mini-md) .main-footer,.sidebar-collapse body:not(.sidebar-mini-md) .main-header{margin-left:0}}@media (max-width:991.98px){body:not(.sidebar-mini-md) .content-wrapper,body:not(.sidebar-mini-md) .content-wrapper:before,body:not(.sidebar-mini-md) .main-footer,body:not(.sidebar-mini-md) .main-footer:before,body:not(.sidebar-mini-md) .main-header,body:not(.sidebar-mini-md) .main-header:before{margin-left:0}}@media (min-width:768px){.sidebar-mini-md .content-wrapper,.sidebar-mini-md .main-footer,.sidebar-mini-md .main-header{transition:margin-left .3s ease-in-out;margin-left:250px}}@media (min-width:768px) and (prefers-reduced-motion:reduce){.sidebar-mini-md .content-wrapper,.sidebar-mini-md .main-footer,.sidebar-mini-md .main-header{transition:none}}@media (min-width:768px){.sidebar-collapse .sidebar-mini-md .content-wrapper,.sidebar-collapse .sidebar-mini-md .main-footer,.sidebar-collapse .sidebar-mini-md .main-header{margin-left:4.6rem}}@media (max-width:991.98px){.sidebar-mini-md .content-wrapper,.sidebar-mini-md .content-wrapper:before,.sidebar-mini-md .main-footer,.sidebar-mini-md .main-footer:before,.sidebar-mini-md .main-header,.sidebar-mini-md .main-header:before{margin-left:4.6rem}}.content-wrapper{background:#f4f6f9}.content-wrapper>.content{padding:0 .5rem}.main-sidebar,.main-sidebar:before{transition:margin-left .3s ease-in-out,width .3s ease-in-out;width:250px}@media (prefers-reduced-motion:reduce){.main-sidebar,.main-sidebar:before{transition:none}}.sidebar-collapse:not(.sidebar-mini):not(.sidebar-mini-md) .main-sidebar,.sidebar-collapse:not(.sidebar-mini):not(.sidebar-mini-md) .main-sidebar:before{box-shadow:none!important}.sidebar-collapse .main-sidebar,.sidebar-collapse .main-sidebar:before{margin-left:-250px}.sidebar-collapse .main-sidebar .nav-sidebar.nav-child-indent .nav-treeview{padding:0}@media (max-width:767.98px){.main-sidebar,.main-sidebar:before{box-shadow:none!important;margin-left:-250px}.sidebar-open .main-sidebar,.sidebar-open .main-sidebar:before{margin-left:0}}:not(.layout-fixed) .main-sidebar{height:inherit;min-height:100%;position:absolute;top:0}.layout-fixed .brand-link{width:250px}.layout-fixed .main-sidebar{left:0}.layout-fixed .control-sidebar,.layout-fixed .main-sidebar{bottom:0;float:none;height:100vh;position:fixed;top:0}.layout-fixed .control-sidebar .control-sidebar-content{height:calc(100vh - 3.5rem - 1px)}@supports (-webkit-touch-callout:none){.layout-fixed .main-sidebar{height:inherit}}.main-footer{background:#fff;border-top:1px solid #dee2e6;color:#869099;padding:1rem}.main-footer.text-sm,.text-sm .main-footer{padding:.812rem}.content-header{padding:15px .5rem}.text-sm .content-header{padding:10px .5rem}.content-header h1{font-size:1.8rem;margin:0}.text-sm .content-header h1{font-size:1.5rem}.content-header .breadcrumb{background:transparent;line-height:1.8rem;margin-bottom:0;padding:0}.text-sm .content-header .breadcrumb{line-height:1.5rem}.hold-transition .content-wrapper,.hold-transition .control-sidebar,.hold-transition .control-sidebar *,.hold-transition .main-footer,.hold-transition .main-header,.hold-transition .main-sidebar,.hold-transition .main-sidebar *{transition:none!important;-webkit-animation-duration:0s!important;animation-duration:0s!important}.main-header{border-bottom:1px solid #dee2e6;z-index:1034}.main-header .nav-link{height:2.5rem;position:relative}.main-header.text-sm .nav-link,.text-sm .main-header .nav-link{height:1.93725rem;padding:.35rem 1rem}.main-header.text-sm .nav-link>.fa,.main-header.text-sm .nav-link>.fab,.main-header.text-sm .nav-link>.far,.main-header.text-sm .nav-link>.fas,.main-header.text-sm .nav-link>.glyphicon,.main-header.text-sm .nav-link>.ion,.text-sm .main-header .nav-link>.fa,.text-sm .main-header .nav-link>.fab,.text-sm .main-header .nav-link>.far,.text-sm .main-header .nav-link>.fas,.text-sm .main-header .nav-link>.glyphicon,.text-sm .main-header .nav-link>.ion{font-size:.875rem}.main-header .navbar-nav .nav-item{margin:0}.main-header .navbar-nav[class*=-right] .dropdown-menu{left:auto;margin-top:-3px;right:0}@media (max-width:575.98px){.main-header .navbar-nav[class*=-right] .dropdown-menu{left:0;right:auto}}.navbar-img{height:calc(3.5rem + 1px)/2;width:auto}.navbar-badge{font-size:.6rem;font-weight:300;padding:2px 4px;position:absolute;right:5px;top:9px}.btn-navbar{background-color:transparent;border-left-width:0}.form-control-navbar{border-right-width:0}.form-control-navbar+.input-group-append{margin-left:0}.btn-navbar,.form-control-navbar{transition:none}.navbar-dark .btn-navbar,.navbar-dark .form-control-navbar{background-color:hsla(0,0%,100%,.2);border:0}.navbar-dark .form-control-navbar::-moz-placeholder{color:hsla(0,0%,100%,.6)}.navbar-dark .form-control-navbar:-ms-input-placeholder{color:hsla(0,0%,100%,.6)}.navbar-dark .form-control-navbar::-ms-input-placeholder{color:hsla(0,0%,100%,.6)}.navbar-dark .form-control-navbar::placeholder{color:hsla(0,0%,100%,.6)}.navbar-dark .form-control-navbar+.input-group-append>.btn-navbar{color:hsla(0,0%,100%,.6)}.navbar-dark .form-control-navbar:focus,.navbar-dark .form-control-navbar:focus+.input-group-append .btn-navbar{background-color:hsla(0,0%,100%,.6);border:0!important;color:#343a40}.navbar-light .btn-navbar,.navbar-light .form-control-navbar{background-color:#f2f4f6;border:0}.navbar-light .form-control-navbar::-moz-placeholder{color:rgba(0,0,0,.6)}.navbar-light .form-control-navbar:-ms-input-placeholder{color:rgba(0,0,0,.6)}.navbar-light .form-control-navbar::-ms-input-placeholder{color:rgba(0,0,0,.6)}.navbar-light .form-control-navbar::placeholder{color:rgba(0,0,0,.6)}.navbar-light .form-control-navbar+.input-group-append>.btn-navbar{color:rgba(0,0,0,.6)}.navbar-light .form-control-navbar:focus,.navbar-light .form-control-navbar:focus+.input-group-append .btn-navbar{background-color:#e9ecef;border:0!important;color:#343a40}.brand-link{display:block;font-size:1.25rem;line-height:1.5;padding:.8125rem .5rem;transition:width .3s ease-in-out;white-space:nowrap}.brand-link:hover{color:#fff;text-decoration:none}.text-sm .brand-link{font-size:inherit}[class*=sidebar-dark] .brand-link{border-bottom:1px solid #4b545c;color:hsla(0,0%,100%,.8)}[class*=sidebar-light] .brand-link{border-bottom:1px solid #dee2e6;color:rgba(0,0,0,.8)}.brand-link .brand-image{float:left;line-height:.8;margin-left:.8rem;margin-right:.5rem;margin-top:-3px;max-height:33px;width:auto}.brand-link .brand-image-xs{float:left;line-height:.8;margin-top:-.1rem;max-height:33px;width:auto}.brand-link .brand-image-xl{line-height:.8;max-height:40px;width:auto}.brand-link .brand-image-xl.single{margin-top:-.3rem}.brand-link.text-sm .brand-image,.text-sm .brand-link .brand-image{height:29px;margin-bottom:-.25rem;margin-left:.95rem;margin-top:-.25rem}.brand-link.text-sm .brand-image-xs,.text-sm .brand-link .brand-image-xs{margin-top:-.2rem;max-height:29px}.brand-link.text-sm .brand-image-xl,.text-sm .brand-link .brand-image-xl{margin-top:-.225rem;max-height:38px}.main-sidebar{height:100vh;overflow-y:hidden;z-index:1038}.main-sidebar a:-moz-focusring{border:0;outline:none}.sidebar{height:calc(100% - 3.5rem - 1px);overflow-y:auto;padding:0 .5rem}.user-panel{position:relative}[class*=sidebar-dark] .user-panel{border-bottom:1px solid #4f5962}[class*=sidebar-light] .user-panel{border-bottom:1px solid #dee2e6}.user-panel,.user-panel .info{overflow:hidden;white-space:nowrap}.user-panel .image{display:inline-block;padding-left:.8rem}.user-panel img{height:auto;width:2.1rem}.user-panel .info{display:inline-block;padding:5px 5px 5px 10px}.user-panel .dropdown-menu,.user-panel .status{font-size:.875rem}.nav-sidebar .nav-item>.nav-link{margin-bottom:.2rem}.nav-sidebar .nav-item>.nav-link .right{transition:transform .3s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-sidebar .nav-item>.nav-link .right{transition:none}}.nav-sidebar .nav-link>.right,.nav-sidebar .nav-link>p>.right{position:absolute;right:1rem;top:.7rem}.nav-sidebar .nav-link>.right i,.nav-sidebar .nav-link>.right span,.nav-sidebar .nav-link>p>.right i,.nav-sidebar .nav-link>p>.right span{margin-left:.5rem}.nav-sidebar .nav-link>.right:nth-child(2),.nav-sidebar .nav-link>p>.right:nth-child(2){right:2.2rem}.nav-sidebar .menu-open>.nav-treeview{display:block}.nav-sidebar .menu-open>.nav-link i.right{transform:rotate(-90deg)}.nav-sidebar>.nav-item{margin-bottom:0}.nav-sidebar>.nav-item .nav-icon{margin-left:.05rem;font-size:1.2rem;margin-right:.2rem;text-align:center;width:1.6rem}.nav-sidebar>.nav-item .nav-icon.fa,.nav-sidebar>.nav-item .nav-icon.fab,.nav-sidebar>.nav-item .nav-icon.far,.nav-sidebar>.nav-item .nav-icon.fas,.nav-sidebar>.nav-item .nav-icon.glyphicon,.nav-sidebar>.nav-item .nav-icon.ion{font-size:1.1rem}.nav-sidebar>.nav-item .float-right{margin-top:3px}.nav-sidebar .nav-treeview{display:none;list-style:none;padding:0}.nav-sidebar .nav-treeview>.nav-item>.nav-link>.nav-icon{width:1.6rem}.nav-sidebar.nav-child-indent .nav-treeview{transition:padding .3s ease-in-out;padding-left:1rem}.text-sm .nav-sidebar.nav-child-indent .nav-treeview{padding-left:.5rem}.nav-sidebar.nav-child-indent.nav-legacy .nav-treeview .nav-treeview{padding-left:2rem;margin-left:-1rem}.text-sm .nav-sidebar.nav-child-indent.nav-legacy .nav-treeview .nav-treeview{padding-left:1rem;margin-left:-.5rem}.nav-sidebar .nav-header{font-size:.9rem;padding:.5rem}.nav-sidebar .nav-header:not(:first-of-type){padding:1.7rem 1rem .5rem}.nav-sidebar .nav-link p{display:inline-block;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;margin:0}#sidebar-overlay{background-color:rgba(0,0,0,.1);bottom:0;display:none;left:0;position:fixed;right:0;top:0;z-index:1037}@media (max-width:991.98px){.sidebar-open #sidebar-overlay{display:block}}[class*=sidebar-light-]{background-color:#fff}[class*=sidebar-light-] .user-panel a:hover{color:#212529}[class*=sidebar-light-] .user-panel .status{background:rgba(0,0,0,.1);color:#343a40}[class*=sidebar-light-] .user-panel .status:active,[class*=sidebar-light-] .user-panel .status:focus,[class*=sidebar-light-] .user-panel .status:hover{background:rgba(0,0,0,.1);color:#212529}[class*=sidebar-light-] .user-panel .dropdown-menu{box-shadow:0 2px 4px rgba(0,0,0,.4);border-color:rgba(0,0,0,.1)}[class*=sidebar-light-] .user-panel .dropdown-item{color:#212529}[class*=sidebar-light-] .nav-sidebar>.nav-item>.nav-link:active,[class*=sidebar-light-] .nav-sidebar>.nav-item>.nav-link:focus{color:#343a40}[class*=sidebar-light-] .nav-sidebar>.nav-item.menu-open>.nav-link,[class*=sidebar-light-] .nav-sidebar>.nav-item:hover>.nav-link{background-color:rgba(0,0,0,.1);color:#212529}[class*=sidebar-light-] .nav-sidebar>.nav-item>.nav-link.active{color:#000;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}[class*=sidebar-light-] .nav-sidebar>.nav-item>.nav-treeview{background:transparent}[class*=sidebar-light-] .nav-header{background:inherit;color:#292d32}[class*=sidebar-light-] .sidebar a{color:#343a40}[class*=sidebar-light-] .sidebar a:hover{text-decoration:none}[class*=sidebar-light-] .nav-treeview>.nav-item>.nav-link{color:#777}[class*=sidebar-light-] .nav-treeview>.nav-item>.nav-link.active,[class*=sidebar-light-] .nav-treeview>.nav-item>.nav-link.active:hover{background-color:rgba(0,0,0,.1);color:#212529}[class*=sidebar-light-] .nav-treeview>.nav-item>.nav-link:hover{background-color:rgba(0,0,0,.1)}[class*=sidebar-light-] .nav-flat .nav-item .nav-treeview .nav-treeview,[class*=sidebar-light-] .nav-flat .nav-item .nav-treeview>.nav-item>.nav-link,[class*=sidebar-light-] .nav-flat .nav-item .nav-treeview>.nav-item>.nav-link.active{border-color:rgba(0,0,0,.1)}[class*=sidebar-dark-]{background-color:#343a40}[class*=sidebar-dark-] .user-panel a:hover{color:#fff}[class*=sidebar-dark-] .user-panel .status{background:hsla(0,0%,100%,.1);color:#c2c7d0}[class*=sidebar-dark-] .user-panel .status:active,[class*=sidebar-dark-] .user-panel .status:focus,[class*=sidebar-dark-] .user-panel .status:hover{background:hsla(0,0%,96.9%,.1);color:#fff}[class*=sidebar-dark-] .user-panel .dropdown-menu{box-shadow:0 2px 4px rgba(0,0,0,.4);border-color:hsla(0,0%,94.9%,.1)}[class*=sidebar-dark-] .user-panel .dropdown-item{color:#212529}[class*=sidebar-dark-] .nav-sidebar>.nav-item>.nav-link:active{color:#c2c7d0}[class*=sidebar-dark-] .nav-sidebar>.nav-item.menu-open>.nav-link,[class*=sidebar-dark-] .nav-sidebar>.nav-item:hover>.nav-link,[class*=sidebar-dark-] .nav-sidebar>.nav-item>.nav-link:focus{background-color:hsla(0,0%,100%,.1);color:#fff}[class*=sidebar-dark-] .nav-sidebar>.nav-item>.nav-link.active{color:#fff;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)}[class*=sidebar-dark-] .nav-sidebar>.nav-item>.nav-treeview{background:transparent}[class*=sidebar-dark-] .nav-header{background:inherit;color:#d0d4db}[class*=sidebar-dark-] .sidebar a{color:#c2c7d0}[class*=sidebar-dark-] .sidebar a:focus,[class*=sidebar-dark-] .sidebar a:hover{text-decoration:none}[class*=sidebar-dark-] .nav-treeview>.nav-item>.nav-link{color:#c2c7d0}[class*=sidebar-dark-] .nav-treeview>.nav-item>.nav-link:focus,[class*=sidebar-dark-] .nav-treeview>.nav-item>.nav-link:hover{background-color:hsla(0,0%,100%,.1);color:#fff}[class*=sidebar-dark-] .nav-treeview>.nav-item>.nav-link.active,[class*=sidebar-dark-] .nav-treeview>.nav-item>.nav-link.active:focus,[class*=sidebar-dark-] .nav-treeview>.nav-item>.nav-link.active:hover{background-color:hsla(0,0%,100%,.9);color:#343a40}[class*=sidebar-dark-] .nav-flat .nav-item .nav-treeview .nav-treeview,[class*=sidebar-dark-] .nav-flat .nav-item .nav-treeview>.nav-item>.nav-link,[class*=sidebar-dark-] .nav-flat .nav-item .nav-treeview>.nav-item>.nav-link.active{border-color:hsla(0,0%,100%,.9)}.sidebar-dark-primary .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-primary .nav-sidebar>.nav-item>.nav-link.active{background-color:#007bff;color:#fff}.sidebar-dark-primary .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-primary .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#007bff}.sidebar-dark-secondary .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-secondary .nav-sidebar>.nav-item>.nav-link.active{background-color:#6c757d;color:#fff}.sidebar-dark-secondary .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-secondary .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#6c757d}.sidebar-dark-success .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-success .nav-sidebar>.nav-item>.nav-link.active{background-color:#28a745;color:#fff}.sidebar-dark-success .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-success .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#28a745}.sidebar-dark-info .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-info .nav-sidebar>.nav-item>.nav-link.active{background-color:#17a2b8;color:#fff}.sidebar-dark-info .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-info .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#17a2b8}.sidebar-dark-warning .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-warning .nav-sidebar>.nav-item>.nav-link.active{background-color:#ffc107;color:#1f2d3d}.sidebar-dark-warning .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-warning .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#ffc107}.sidebar-dark-danger .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-danger .nav-sidebar>.nav-item>.nav-link.active{background-color:#dc3545;color:#fff}.sidebar-dark-danger .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-danger .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#dc3545}.sidebar-dark-light .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-light .nav-sidebar>.nav-item>.nav-link.active{background-color:#f8f9fa;color:#1f2d3d}.sidebar-dark-light .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-light .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#f8f9fa}.sidebar-dark-dark .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-dark .nav-sidebar>.nav-item>.nav-link.active{background-color:#343a40;color:#fff}.sidebar-dark-dark .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-dark .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#343a40}.sidebar-dark-lightblue .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-lightblue .nav-sidebar>.nav-item>.nav-link.active{background-color:#3c8dbc;color:#fff}.sidebar-dark-lightblue .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-lightblue .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#3c8dbc}.sidebar-dark-navy .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-navy .nav-sidebar>.nav-item>.nav-link.active{background-color:#001f3f;color:#fff}.sidebar-dark-navy .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-navy .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#001f3f}.sidebar-dark-olive .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-olive .nav-sidebar>.nav-item>.nav-link.active{background-color:#3d9970;color:#fff}.sidebar-dark-olive .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-olive .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#3d9970}.sidebar-dark-lime .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-lime .nav-sidebar>.nav-item>.nav-link.active{background-color:#01ff70;color:#1f2d3d}.sidebar-dark-lime .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-lime .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#01ff70}.sidebar-dark-fuchsia .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-fuchsia .nav-sidebar>.nav-item>.nav-link.active{background-color:#f012be;color:#fff}.sidebar-dark-fuchsia .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-fuchsia .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#f012be}.sidebar-dark-maroon .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-maroon .nav-sidebar>.nav-item>.nav-link.active{background-color:#d81b60;color:#fff}.sidebar-dark-maroon .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-maroon .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#d81b60}.sidebar-dark-blue .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-blue .nav-sidebar>.nav-item>.nav-link.active{background-color:#007bff;color:#fff}.sidebar-dark-blue .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-blue .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#007bff}.sidebar-dark-indigo .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-indigo .nav-sidebar>.nav-item>.nav-link.active{background-color:#6610f2;color:#fff}.sidebar-dark-indigo .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-indigo .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#6610f2}.sidebar-dark-purple .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-purple .nav-sidebar>.nav-item>.nav-link.active{background-color:#6f42c1;color:#fff}.sidebar-dark-purple .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-purple .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#6f42c1}.sidebar-dark-pink .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-pink .nav-sidebar>.nav-item>.nav-link.active{background-color:#e83e8c;color:#fff}.sidebar-dark-pink .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-pink .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#e83e8c}.sidebar-dark-red .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-red .nav-sidebar>.nav-item>.nav-link.active{background-color:#dc3545;color:#fff}.sidebar-dark-red .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-red .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#dc3545}.sidebar-dark-orange .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-orange .nav-sidebar>.nav-item>.nav-link.active{background-color:#fd7e14;color:#1f2d3d}.sidebar-dark-orange .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-orange .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#fd7e14}.sidebar-dark-yellow .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-yellow .nav-sidebar>.nav-item>.nav-link.active{background-color:#ffc107;color:#1f2d3d}.sidebar-dark-yellow .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-yellow .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#ffc107}.sidebar-dark-green .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-green .nav-sidebar>.nav-item>.nav-link.active{background-color:#28a745;color:#fff}.sidebar-dark-green .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-green .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#28a745}.sidebar-dark-teal .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-teal .nav-sidebar>.nav-item>.nav-link.active{background-color:#20c997;color:#fff}.sidebar-dark-teal .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-teal .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#20c997}.sidebar-dark-cyan .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-cyan .nav-sidebar>.nav-item>.nav-link.active{background-color:#17a2b8;color:#fff}.sidebar-dark-cyan .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-cyan .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#17a2b8}.sidebar-dark-white .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-white .nav-sidebar>.nav-item>.nav-link.active{background-color:#fff;color:#1f2d3d}.sidebar-dark-white .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-white .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#fff}.sidebar-dark-gray .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-gray .nav-sidebar>.nav-item>.nav-link.active{background-color:#6c757d;color:#fff}.sidebar-dark-gray .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-gray .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#6c757d}.sidebar-dark-gray-dark .nav-sidebar>.nav-item>.nav-link.active,.sidebar-light-gray-dark .nav-sidebar>.nav-item>.nav-link.active{background-color:#343a40;color:#fff}.sidebar-dark-gray-dark .nav-sidebar.nav-legacy>.nav-item>.nav-link.active,.sidebar-light-gray-dark .nav-sidebar.nav-legacy>.nav-item>.nav-link.active{border-color:#343a40}.sidebar-mini-md .main-sidebar.sidebar-focused .nav-compact.nav-sidebar.nav-child-indent:not(.nav-flat) .nav-treeview,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand) .nav-compact.nav-sidebar.nav-child-indent:not(.nav-flat) .nav-treeview,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand):hover .nav-compact.nav-sidebar.nav-child-indent:not(.nav-flat) .nav-treeview,.sidebar-mini .main-sidebar.sidebar-focused .nav-compact.nav-sidebar.nav-child-indent:not(.nav-flat) .nav-treeview,.sidebar-mini .main-sidebar:not(.sidebar-no-expand) .nav-compact.nav-sidebar.nav-child-indent:not(.nav-flat) .nav-treeview,.sidebar-mini .main-sidebar:not(.sidebar-no-expand):hover .nav-compact.nav-sidebar.nav-child-indent:not(.nav-flat) .nav-treeview{padding-left:1rem;margin-left:-.5rem}.nav-flat{margin:-.25rem -.5rem 0}.nav-flat .nav-item>.nav-link{border-radius:0;margin-bottom:0}.nav-flat .nav-item>.nav-link>.nav-icon{margin-left:.55rem}.nav-flat:not(.nav-child-indent) .nav-treeview .nav-item>.nav-link>.nav-icon{margin-left:.4rem}.nav-flat.nav-child-indent .nav-treeview{padding-left:0}.nav-flat.nav-child-indent .nav-treeview .nav-icon{margin-left:.85rem}.nav-flat.nav-child-indent .nav-treeview .nav-treeview{border-left:.2rem solid}.nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-icon{margin-left:1.15rem}.nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:1.45rem}.nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:1.75rem}.nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:2.05rem}.sidebar-collapse .nav-flat.nav-child-indent .nav-treeview .nav-icon{margin-left:.55rem}.sidebar-collapse .nav-flat.nav-child-indent .nav-treeview .nav-link{padding-left:.8rem}.sidebar-collapse .nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-icon{margin-left:.35rem}.sidebar-collapse .nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:.15rem}.sidebar-collapse .nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:-.15rem}.sidebar-collapse .nav-flat.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:-.35rem}.sidebar-mini-md .main-sidebar.sidebar-focused .nav-flat.nav-compact.nav-sidebar .nav-treeview .nav-icon,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-compact.nav-sidebar .nav-treeview .nav-icon,.sidebar-mini .main-sidebar.sidebar-focused .nav-flat.nav-compact.nav-sidebar .nav-treeview .nav-icon,.sidebar-mini .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-compact.nav-sidebar .nav-treeview .nav-icon{margin-left:.4rem}.sidebar-mini-md .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-icon,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-icon,.sidebar-mini .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-icon,.sidebar-mini .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-icon{margin-left:.85rem}.sidebar-mini-md .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-icon,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-icon{margin-left:1.15rem}.sidebar-mini-md .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:1.45rem}.sidebar-mini-md .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:1.75rem}.sidebar-mini-md .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini-md .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar.sidebar-focused .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon,.sidebar-mini .main-sidebar:not(.sidebar-no-expand):hover .nav-flat.nav-sidebar.nav-child-indent .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-treeview .nav-icon{margin-left:2.05rem}.nav-flat .nav-icon{transition:margin-left .3s ease-in-out}@media (prefers-reduced-motion:reduce){.nav-flat .nav-icon{transition:none}}.nav-flat .nav-treeview .nav-icon{margin-left:-.2rem}.nav-flat.nav-sidebar>.nav-item .nav-treeview,.nav-flat.nav-sidebar>.nav-item>.nav-treeview{background:hsla(0,0%,100%,.05)}.nav-flat.nav-sidebar>.nav-item .nav-treeview .nav-item>.nav-link,.nav-flat.nav-sidebar>.nav-item>.nav-treeview .nav-item>.nav-link{border-left:.2rem solid}.nav-legacy{margin:-.25rem -.5rem 0}.nav-legacy.nav-sidebar .nav-item>.nav-link{border-radius:0;margin-bottom:0}.nav-legacy.nav-sidebar .nav-item>.nav-link>.nav-icon{margin-left:.55rem}.text-sm .nav-legacy.nav-sidebar .nav-item>.nav-link>.nav-icon{margin-left:.75rem}.nav-legacy.nav-sidebar>.nav-item>.nav-link.active{background:inherit;border-left:3px solid transparent;box-shadow:none}.nav-legacy.nav-sidebar>.nav-item>.nav-link.active>.nav-icon{margin-left:calc(.55rem - 3px)}.text-sm .nav-legacy.nav-sidebar.nav-flat .nav-treeview .nav-item>.nav-link>.nav-icon,.text-sm .nav-legacy.nav-sidebar>.nav-item>.nav-link.active>.nav-icon{margin-left:calc(.75rem - 3px)}.sidebar-mini-md .nav-legacy>.nav-item .nav-link .nav-icon,.sidebar-mini .nav-legacy>.nav-item .nav-link .nav-icon{transition:margin-left .3s ease-in-out;margin-left:.75rem}@media (prefers-reduced-motion:reduce){.sidebar-mini-md .nav-legacy>.nav-item .nav-link .nav-icon,.sidebar-mini .nav-legacy>.nav-item .nav-link .nav-icon{transition:none}}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview,.sidebar-mini.sidebar-collapse .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview{padding-left:1rem}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview .nav-treeview,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview .nav-treeview,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview .nav-treeview,.sidebar-mini.sidebar-collapse .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview .nav-treeview{padding-left:2rem;margin-left:-1rem}.sidebar-mini-md.sidebar-collapse.text-sm .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview,.sidebar-mini-md.sidebar-collapse.text-sm .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview,.sidebar-mini.sidebar-collapse.text-sm .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview,.sidebar-mini.sidebar-collapse.text-sm .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview{padding-left:.5rem}.sidebar-mini-md.sidebar-collapse.text-sm .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview .nav-treeview,.sidebar-mini-md.sidebar-collapse.text-sm .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview .nav-treeview,.sidebar-mini.sidebar-collapse.text-sm .main-sidebar.sidebar-focused .nav-legacy.nav-child-indent .nav-treeview .nav-treeview,.sidebar-mini.sidebar-collapse.text-sm .main-sidebar:hover .nav-legacy.nav-child-indent .nav-treeview .nav-treeview{padding-left:1rem;margin-left:-.5rem}.sidebar-mini-md.sidebar-collapse .nav-legacy>.nav-item>.nav-link .nav-icon,.sidebar-mini.sidebar-collapse .nav-legacy>.nav-item>.nav-link .nav-icon{margin-left:.55rem}.sidebar-mini-md.sidebar-collapse .nav-legacy>.nav-item>.nav-link.active>.nav-icon,.sidebar-mini.sidebar-collapse .nav-legacy>.nav-item>.nav-link.active>.nav-icon{margin-left:.36rem}.sidebar-mini-md.sidebar-collapse .nav-legacy.nav-child-indent .nav-treeview .nav-treeview,.sidebar-mini.sidebar-collapse .nav-legacy.nav-child-indent .nav-treeview .nav-treeview{padding-left:0;margin-left:0}.sidebar-mini-md.sidebar-collapse.text-sm .nav-legacy>.nav-item>.nav-link .nav-icon,.sidebar-mini.sidebar-collapse.text-sm .nav-legacy>.nav-item>.nav-link .nav-icon{margin-left:.75rem}.sidebar-mini-md.sidebar-collapse.text-sm .nav-legacy>.nav-item>.nav-link.active>.nav-icon,.sidebar-mini.sidebar-collapse.text-sm .nav-legacy>.nav-item>.nav-link.active>.nav-icon{margin-left:calc(.75rem - 3px)}[class*=sidebar-dark] .nav-legacy.nav-sidebar>.nav-item .nav-treeview,[class*=sidebar-dark] .nav-legacy.nav-sidebar>.nav-item>.nav-treeview{background:hsla(0,0%,100%,.05)}[class*=sidebar-dark] .nav-legacy.nav-sidebar>.nav-item>.nav-link.active{color:#fff}[class*=sidebar-dark] .nav-legacy .nav-treeview>.nav-item>.nav-link.active,[class*=sidebar-dark] .nav-legacy .nav-treeview>.nav-item>.nav-link:focus,[class*=sidebar-dark] .nav-legacy .nav-treeview>.nav-item>.nav-link:hover{background:none;color:#fff}[class*=sidebar-light] .nav-legacy.nav-sidebar>.nav-item .nav-treeview,[class*=sidebar-light] .nav-legacy.nav-sidebar>.nav-item>.nav-treeview{background:rgba(0,0,0,.05)}[class*=sidebar-light] .nav-legacy.nav-sidebar>.nav-item>.nav-link.active{color:#000}[class*=sidebar-light] .nav-legacy .nav-treeview>.nav-item>.nav-link.active,[class*=sidebar-light] .nav-legacy .nav-treeview>.nav-item>.nav-link:focus,[class*=sidebar-light] .nav-legacy .nav-treeview>.nav-item>.nav-link:hover{background:none;color:#000}.nav-collapse-hide-child .menu-open>.nav-treeview{max-height:-webkit-min-content;max-height:-moz-min-content;max-height:min-content;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.sidebar-collapse .nav-collapse-hide-child .menu-open>.nav-treeview{max-height:0;-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .nav-collapse-hide-child .menu-open>.nav-treeview,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .nav-collapse-hide-child .menu-open>.nav-treeview,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .nav-collapse-hide-child .menu-open>.nav-treeview,.sidebar-mini.sidebar-collapse .main-sidebar:hover .nav-collapse-hide-child .menu-open>.nav-treeview{max-height:-webkit-min-content;max-height:-moz-min-content;max-height:min-content;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both}.nav-compact .nav-header,.nav-compact .nav-link{padding-top:.25rem;padding-bottom:.25rem}.nav-compact .nav-header:not(:first-of-type){padding-top:.75rem;padding-bottom:.25rem}.nav-compact .nav-link>.right,.nav-compact .nav-link>p>.right{top:.465rem}.text-sm .nav-compact .nav-link>.right,.text-sm .nav-compact .nav-link>p>.right{top:.7rem}[class*=sidebar-dark] .btn-sidebar,[class*=sidebar-dark] .form-control-sidebar{background:#3f474e;border:1px solid #56606a;color:#fff}[class*=sidebar-dark] .btn-sidebar:focus,[class*=sidebar-dark] .form-control-sidebar:focus{border:1px solid #7a8793}[class*=sidebar-dark] .btn-sidebar:hover{background:#454d55}[class*=sidebar-dark] .btn-sidebar:focus{background:#4b545c}[class*=sidebar-light] .btn-sidebar,[class*=sidebar-light] .form-control-sidebar{background:#f2f2f2;border:1px solid #d9d9d9;color:#1f2d3d}[class*=sidebar-light] .btn-sidebar:focus,[class*=sidebar-light] .form-control-sidebar:focus{border:1px solid #b3b3b3}[class*=sidebar-light] .btn-sidebar:hover{background:#ececec}[class*=sidebar-light] .btn-sidebar:focus{background:#e6e6e6}.sidebar .form-inline .input-group{width:100%}.sidebar nav .form-inline{margin-bottom:.2rem}.layout-boxed.sidebar-collapse .main-sidebar{margin-left:0}.layout-boxed .content-wrapper,.layout-boxed .main-footer,.layout-boxed .main-header{z-index:9999;position:relative}.logo-xl,.logo-xs{opacity:1;position:absolute;visibility:visible}.logo-xl.brand-image-xs,.logo-xs.brand-image-xs{left:18px;top:12px}.logo-xl.brand-image-xl,.logo-xs.brand-image-xl{left:12px;top:6px}.logo-xs{opacity:0;visibility:hidden}.logo-xs.brand-image-xl{left:16px;top:8px}.brand-link.logo-switch:before{content:"\A0"}@media (min-width:992px){.sidebar-mini .nav-sidebar,.sidebar-mini .nav-sidebar .nav-link,.sidebar-mini .nav-sidebar>.nav-header{white-space:nowrap;overflow:hidden}.sidebar-mini.sidebar-collapse .d-hidden-mini{display:none}.sidebar-mini.sidebar-collapse .content-wrapper,.sidebar-mini.sidebar-collapse .main-footer,.sidebar-mini.sidebar-collapse .main-header{margin-left:4.6rem!important}.sidebar-mini.sidebar-collapse .nav-sidebar .nav-header{display:none}.sidebar-mini.sidebar-collapse .nav-sidebar .nav-link p{width:0}.sidebar-mini.sidebar-collapse .brand-text,.sidebar-mini.sidebar-collapse .nav-sidebar .nav-link p,.sidebar-mini.sidebar-collapse .sidebar .user-panel>.info{margin-left:-10px}.sidebar-mini.sidebar-collapse .brand-text,.sidebar-mini.sidebar-collapse .logo-xl,.sidebar-mini.sidebar-collapse .nav-sidebar .nav-link p,.sidebar-mini.sidebar-collapse .sidebar .user-panel>.info{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:hidden}.sidebar-mini.sidebar-collapse .logo-xs{display:inline-block;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:visible}.sidebar-mini.sidebar-collapse .main-sidebar{overflow-x:hidden}.sidebar-mini.sidebar-collapse .main-sidebar,.sidebar-mini.sidebar-collapse .main-sidebar:before{margin-left:0;width:4.6rem}.sidebar-mini.sidebar-collapse .main-sidebar .user-panel .image{float:none}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .brand-link,.sidebar-mini.sidebar-collapse .main-sidebar:hover,.sidebar-mini.sidebar-collapse .main-sidebar:hover .brand-link{width:250px}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .user-panel,.sidebar-mini.sidebar-collapse .main-sidebar:hover .user-panel{text-align:left}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .user-panel .image,.sidebar-mini.sidebar-collapse .main-sidebar:hover .user-panel .image{float:left}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .brand-text,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .logo-xl,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .nav-sidebar .nav-link p,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .user-panel>.info,.sidebar-mini.sidebar-collapse .main-sidebar:hover .brand-text,.sidebar-mini.sidebar-collapse .main-sidebar:hover .logo-xl,.sidebar-mini.sidebar-collapse .main-sidebar:hover .nav-sidebar .nav-link p,.sidebar-mini.sidebar-collapse .main-sidebar:hover .user-panel>.info{display:inline-block;margin-left:0;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:visible}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .logo-xs,.sidebar-mini.sidebar-collapse .main-sidebar:hover .logo-xs{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:hidden}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .brand-image,.sidebar-mini.sidebar-collapse .main-sidebar:hover .brand-image{margin-right:.5rem}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .sidebar-form,.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .user-panel>.info,.sidebar-mini.sidebar-collapse .main-sidebar:hover .sidebar-form,.sidebar-mini.sidebar-collapse .main-sidebar:hover .user-panel>.info{display:block!important;-webkit-transform:translateZ(0)}.sidebar-mini.sidebar-collapse .main-sidebar.sidebar-focused .nav-sidebar>.nav-item>.nav-link>span,.sidebar-mini.sidebar-collapse .main-sidebar:hover .nav-sidebar>.nav-item>.nav-link>span{display:inline-block!important}.sidebar-mini.sidebar-collapse .visible-sidebar-mini{display:block!important}.sidebar-mini.sidebar-collapse.layout-fixed .main-sidebar:hover .brand-link{width:250px}.sidebar-mini.sidebar-collapse.layout-fixed .brand-link{width:4.6rem}}@media (max-width:991.98px){.sidebar-mini.sidebar-collapse .main-sidebar{box-shadow:none!important}}@media (min-width:768px){.sidebar-mini-md .nav-sidebar,.sidebar-mini-md .nav-sidebar .nav-link,.sidebar-mini-md .nav-sidebar>.nav-header{white-space:nowrap;overflow:hidden}.sidebar-mini-md.sidebar-collapse .d-hidden-mini{display:none}.sidebar-mini-md.sidebar-collapse .content-wrapper,.sidebar-mini-md.sidebar-collapse .main-footer,.sidebar-mini-md.sidebar-collapse .main-header{margin-left:4.6rem!important}.sidebar-mini-md.sidebar-collapse .nav-sidebar .nav-header{display:none}.sidebar-mini-md.sidebar-collapse .nav-sidebar .nav-link p{width:0}.sidebar-mini-md.sidebar-collapse .brand-text,.sidebar-mini-md.sidebar-collapse .nav-sidebar .nav-link p,.sidebar-mini-md.sidebar-collapse .sidebar .user-panel>.info{margin-left:-10px}.sidebar-mini-md.sidebar-collapse .brand-text,.sidebar-mini-md.sidebar-collapse .logo-xl,.sidebar-mini-md.sidebar-collapse .nav-sidebar .nav-link p,.sidebar-mini-md.sidebar-collapse .sidebar .user-panel>.info{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:hidden}.sidebar-mini-md.sidebar-collapse .logo-xs{display:inline-block;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:visible}.sidebar-mini-md.sidebar-collapse .main-sidebar{overflow-x:hidden}.sidebar-mini-md.sidebar-collapse .main-sidebar,.sidebar-mini-md.sidebar-collapse .main-sidebar:before{margin-left:0;width:4.6rem}.sidebar-mini-md.sidebar-collapse .main-sidebar .user-panel .image{float:none}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused,.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .brand-link,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .brand-link{width:250px}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .user-panel,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .user-panel{text-align:left}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .user-panel .image,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .user-panel .image{float:left}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .brand-text,.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .logo-xl,.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .nav-sidebar .nav-link p,.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .user-panel>.info,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .brand-text,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .logo-xl,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .nav-sidebar .nav-link p,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .user-panel>.info{display:inline-block;margin-left:0;-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:visible}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .logo-xs,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .logo-xs{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:hidden}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .brand-image,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .brand-image{margin-right:.5rem}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .sidebar-form,.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .user-panel>.info,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .sidebar-form,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .user-panel>.info{display:block!important;-webkit-transform:translateZ(0)}.sidebar-mini-md.sidebar-collapse .main-sidebar.sidebar-focused .nav-sidebar>.nav-item>.nav-link>span,.sidebar-mini-md.sidebar-collapse .main-sidebar:hover .nav-sidebar>.nav-item>.nav-link>span{display:inline-block!important}.sidebar-mini-md.sidebar-collapse .visible-sidebar-mini{display:block!important}.sidebar-mini-md.sidebar-collapse.layout-fixed .main-sidebar:hover .brand-link{width:250px}.sidebar-mini-md.sidebar-collapse.layout-fixed .brand-link{width:4.6rem}}@media (max-width:767.98px){.sidebar-mini-md.sidebar-collapse .main-sidebar{box-shadow:none!important}}@-webkit-keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@-webkit-keyframes fadeOut{0%{opacity:1}to{opacity:0}}@keyframes fadeOut{0%{opacity:1}to{opacity:0}}.sidebar-collapse .main-sidebar.sidebar-focused .nav-header,.sidebar-collapse .main-sidebar:hover .nav-header{display:inline-block}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover{width:4.6rem}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .nav-header,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .nav-header{display:none}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .brand-link,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .brand-link{width:4.6rem!important}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .user-panel .image,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .user-panel .image{float:none!important}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .logo-xs,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .logo-xs{-webkit-animation-name:fadeIn;animation-name:fadeIn;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:visible}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .logo-xl,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .logo-xl{-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:hidden}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .nav-sidebar.nav-child-indent .nav-treeview,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .nav-sidebar.nav-child-indent .nav-treeview{padding-left:0}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .brand-text,.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .nav-sidebar .nav-link p,.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .user-panel>.info,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .brand-text,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .nav-sidebar .nav-link p,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .user-panel>.info{margin-left:-10px;-webkit-animation-name:fadeOut;animation-name:fadeOut;-webkit-animation-duration:.3s;animation-duration:.3s;-webkit-animation-fill-mode:both;animation-fill-mode:both;visibility:hidden;width:0}.sidebar-collapse .sidebar-no-expand.main-sidebar.sidebar-focused .nav-sidebar>.nav-item .nav-icon,.sidebar-collapse .sidebar-no-expand.main-sidebar:hover .nav-sidebar>.nav-item .nav-icon{margin-right:0}.nav-sidebar{position:relative}.nav-sidebar:hover{overflow:visible}.nav-sidebar>.nav-header,.sidebar-form{overflow:hidden;text-overflow:clip}.nav-sidebar .nav-item>.nav-link{position:relative}.nav-sidebar .nav-item>.nav-link>.float-right{margin-top:-7px;position:absolute;right:10px;top:50%}.main-sidebar .brand-text,.main-sidebar .logo-xl,.main-sidebar .logo-xs,.sidebar .nav-link p,.sidebar .user-panel .info{transition:margin-left .3s linear,opacity .3s ease,visibility .3s ease}@media (prefers-reduced-motion:reduce){.main-sidebar .brand-text,.main-sidebar .logo-xl,.main-sidebar .logo-xs,.sidebar .nav-link p,.sidebar .user-panel .info{transition:none}}html.control-sidebar-animate{overflow-x:hidden}.control-sidebar{bottom:calc(3.5rem + 1px);position:absolute;top:calc(3.5rem + 1px);z-index:1031}.control-sidebar,.control-sidebar:before{bottom:calc(3.5rem + 1px);display:none;right:-250px;width:250px;transition:right .3s ease-in-out,display .3s ease-in-out}@media (prefers-reduced-motion:reduce){.control-sidebar,.control-sidebar:before{transition:none}}.control-sidebar:before{content:"";display:block;position:fixed;top:0;z-index:-1}body.text-sm .control-sidebar{bottom:calc(2.9365rem + 1px);top:calc(2.93725rem + 1px)}.main-header.text-sm~.control-sidebar{top:calc(2.93725rem + 1px)}.main-footer.text-sm~.control-sidebar{bottom:calc(2.9365rem + 1px)}.control-sidebar-push-slide .content-wrapper,.control-sidebar-push-slide .main-footer{transition:margin-right .3s ease-in-out}@media (prefers-reduced-motion:reduce){.control-sidebar-push-slide .content-wrapper,.control-sidebar-push-slide .main-footer{transition:none}}.control-sidebar-open .control-sidebar{display:block}.control-sidebar-open .control-sidebar,.control-sidebar-open .control-sidebar:before{right:0}.control-sidebar-open.control-sidebar-push-slide .content-wrapper,.control-sidebar-open.control-sidebar-push-slide .main-footer,.control-sidebar-open.control-sidebar-push .content-wrapper,.control-sidebar-open.control-sidebar-push .main-footer{margin-right:250px}.control-sidebar-slide-open .control-sidebar{display:block}.control-sidebar-slide-open .control-sidebar,.control-sidebar-slide-open .control-sidebar:before{right:0;transition:right .3s ease-in-out,display .3s ease-in-out}@media (prefers-reduced-motion:reduce){.control-sidebar-slide-open .control-sidebar,.control-sidebar-slide-open .control-sidebar:before{transition:none}}.control-sidebar-slide-open.control-sidebar-push-slide .content-wrapper,.control-sidebar-slide-open.control-sidebar-push-slide .main-footer,.control-sidebar-slide-open.control-sidebar-push .content-wrapper,.control-sidebar-slide-open.control-sidebar-push .main-footer{margin-right:250px}.control-sidebar-dark,.control-sidebar-dark .nav-link,.control-sidebar-dark a{color:#c2c7d0}.control-sidebar-dark{background:#343a40}.control-sidebar-dark a:hover,.control-sidebar-dark h1,.control-sidebar-dark h2,.control-sidebar-dark h3,.control-sidebar-dark h4,.control-sidebar-dark h5,.control-sidebar-dark h6,.control-sidebar-dark label{color:#fff}.control-sidebar-dark .nav-tabs{background-color:hsla(0,0%,100%,.1);border-bottom:0;margin-bottom:5px}.control-sidebar-dark .nav-tabs .nav-item{margin:0}.control-sidebar-dark .nav-tabs .nav-link{border-radius:0;padding:10px 20px;position:relative;text-align:center}.control-sidebar-dark .nav-tabs .nav-link,.control-sidebar-dark .nav-tabs .nav-link.active,.control-sidebar-dark .nav-tabs .nav-link:active,.control-sidebar-dark .nav-tabs .nav-link:focus,.control-sidebar-dark .nav-tabs .nav-link:hover{border:0}.control-sidebar-dark .nav-tabs .nav-link.active,.control-sidebar-dark .nav-tabs .nav-link:active,.control-sidebar-dark .nav-tabs .nav-link:focus,.control-sidebar-dark .nav-tabs .nav-link:hover{border-bottom-color:transparent;border-left-color:transparent;border-top-color:transparent;color:#fff}.control-sidebar-dark .nav-tabs .nav-link.active{background-color:#343a40}.control-sidebar-dark .tab-pane{padding:10px 15px}.control-sidebar-light{color:#4b545c;background:#fff;border-left:1px solid #dee2e6}.text-sm .dropdown-menu{font-size:.875rem!important}.text-sm .dropdown-toggle:after{vertical-align:.2rem}.dropdown-item-title{font-size:1rem;margin:0}.dropdown-icon:after{margin-left:0}.dropdown-menu-lg{max-width:300px;min-width:280px;padding:0}.dropdown-menu-lg .dropdown-divider{margin:0}.dropdown-menu-lg .dropdown-item{padding:.5rem 1rem}.dropdown-menu-lg p{margin:0;white-space:normal}.dropdown-submenu{position:relative}.dropdown-submenu>a:after{border-top:.3em solid transparent;border-right:0;border-bottom:.3em solid transparent;border-left:.3em solid;float:right;margin-left:.5rem;margin-top:.5rem}.dropdown-submenu>.dropdown-menu{left:100%;margin-left:0;margin-top:0;top:0}.dropdown-hover.dropdown-submenu:hover>.dropdown-menu,.dropdown-hover .dropdown-submenu:hover>.dropdown-menu,.dropdown-hover.nav-item.dropdown:hover>.dropdown-menu,.dropdown-hover:hover>.dropdown-menu{display:block}.dropdown-menu-xl{max-width:420px;min-width:360px;padding:0}.dropdown-menu-xl .dropdown-divider{margin:0}.dropdown-menu-xl .dropdown-item{padding:.5rem 1rem}.dropdown-menu-xl p{margin:0;white-space:normal}.dropdown-footer,.dropdown-header{display:block;font-size:.875rem;padding:.5rem 1rem;text-align:center}.open:not(.dropup)>.animated-dropdown-menu{-webkit-animation:flipInX .7s both;animation:flipInX .7s both;-webkit-backface-visibility:visible!important;backface-visibility:visible!important}@-webkit-keyframes flipInX{0%{transform:perspective(400px) rotateX(90deg);transition-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotateX(-20deg);transition-timing-function:ease-in}60%{transform:perspective(400px) rotateX(10deg);opacity:1}80%{transform:perspective(400px) rotateX(-5deg)}to{transform:perspective(400px)}}@keyframes flipInX{0%{transform:perspective(400px) rotateX(90deg);transition-timing-function:ease-in;opacity:0}40%{transform:perspective(400px) rotateX(-20deg);transition-timing-function:ease-in}60%{transform:perspective(400px) rotateX(10deg);opacity:1}80%{transform:perspective(400px) rotateX(-5deg)}to{transform:perspective(400px)}}.navbar-custom-menu>.navbar-nav>li{position:relative}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:0;left:auto}@media (max-width:767.98px){.navbar-custom-menu>.navbar-nav{float:right}.navbar-custom-menu>.navbar-nav>li{position:static}.navbar-custom-menu>.navbar-nav>li>.dropdown-menu{position:absolute;right:5%;left:auto;border:1px solid #ddd;background:#fff}}.navbar-nav>.user-menu>.nav-link:after{content:none}.navbar-nav>.user-menu>.dropdown-menu{border-top-left-radius:0;border-top-right-radius:0;padding:0;width:280px}.navbar-nav>.user-menu>.dropdown-menu,.navbar-nav>.user-menu>.dropdown-menu>.user-body{border-bottom-right-radius:4px;border-bottom-left-radius:4px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header{height:175px;padding:10px;text-align:center}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>img{z-index:5;height:90px;width:90px;border:3px solid hsla(0,0%,100%,.2)}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p{z-index:5;font-size:17px;margin-top:10px}.navbar-nav>.user-menu>.dropdown-menu>li.user-header>p>small{display:block;font-size:12px}.navbar-nav>.user-menu>.dropdown-menu>.user-body{border-bottom:1px solid #495057;border-top:1px solid #dee2e6;padding:15px}.navbar-nav>.user-menu>.dropdown-menu>.user-body:after{display:block;clear:both;content:""}@media (min-width:576px){.navbar-nav>.user-menu>.dropdown-menu>.user-body a{background:#fff!important;color:#495057!important}}.navbar-nav>.user-menu>.dropdown-menu>.user-footer{background-color:#f8f9fa;padding:10px}.navbar-nav>.user-menu>.dropdown-menu>.user-footer:after{display:block;clear:both;content:""}.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default{color:#6c757d}@media (min-width:576px){.navbar-nav>.user-menu>.dropdown-menu>.user-footer .btn-default:hover{background-color:#f8f9fa}}.navbar-nav>.user-menu .user-image{border-radius:50%;float:left;height:2.1rem;margin-right:10px;margin-top:-2px;width:2.1rem}@media (min-width:576px){.navbar-nav>.user-menu .user-image{float:none;line-height:10px;margin-right:.4rem;margin-top:-8px}}.nav-pills .nav-link{color:#6c757d}.nav-pills .nav-link:not(.active):hover{color:#007bff}.nav-pills .nav-item.dropdown.show .nav-link:hover{color:#fff}.nav-tabs.flex-column{border-bottom:0;border-right:1px solid #dee2e6}.nav-tabs.flex-column .nav-link{border-bottom-left-radius:.25rem;border-top-right-radius:0;margin-right:-1px}.nav-tabs.flex-column .nav-link:focus,.nav-tabs.flex-column .nav-link:hover{border-color:#e9ecef transparent #e9ecef #e9ecef}.nav-tabs.flex-column .nav-item.show .nav-link,.nav-tabs.flex-column .nav-link.active{border-color:#dee2e6 transparent #dee2e6 #dee2e6}.nav-tabs.flex-column.nav-tabs-right{border-left:1px solid #dee2e6;border-right:0}.nav-tabs.flex-column.nav-tabs-right .nav-link{border-bottom-left-radius:0;border-bottom-right-radius:.25rem;border-top-left-radius:0;border-top-right-radius:.25rem;margin-left:-1px}.nav-tabs.flex-column.nav-tabs-right .nav-link:focus,.nav-tabs.flex-column.nav-tabs-right .nav-link:hover{border-color:#e9ecef #e9ecef #e9ecef transparent}.nav-tabs.flex-column.nav-tabs-right .nav-item.show .nav-link,.nav-tabs.flex-column.nav-tabs-right .nav-link.active{border-color:#dee2e6 #dee2e6 #dee2e6 transparent}.navbar-no-expand{flex-direction:row}.navbar-no-expand .nav-link{padding-left:1rem;padding-right:1rem}.navbar-no-expand .dropdown-menu{position:absolute}.navbar-light{background-color:#f8f9fa}.navbar-dark{background-color:#343a40}.navbar-primary{background-color:#007bff}.navbar-secondary{background-color:#6c757d}.navbar-success{background-color:#28a745}.navbar-info{background-color:#17a2b8}.navbar-warning{background-color:#ffc107}.navbar-danger{background-color:#dc3545}.navbar-lightblue{background-color:#3c8dbc}.navbar-navy{background-color:#001f3f}.navbar-olive{background-color:#3d9970}.navbar-lime{background-color:#01ff70}.navbar-fuchsia{background-color:#f012be}.navbar-maroon{background-color:#d81b60}.navbar-blue{background-color:#007bff}.navbar-indigo{background-color:#6610f2}.navbar-purple{background-color:#6f42c1}.navbar-pink{background-color:#e83e8c}.navbar-red{background-color:#dc3545}.navbar-orange{background-color:#fd7e14}.navbar-yellow{background-color:#ffc107}.navbar-green{background-color:#28a745}.navbar-teal{background-color:#20c997}.navbar-cyan{background-color:#17a2b8}.navbar-white{background-color:#fff}.navbar-gray{background-color:#6c757d}.navbar-gray-dark{background-color:#343a40}.form-group.has-icon{position:relative}.form-group.has-icon .form-control{padding-right:35px}.form-group.has-icon .form-icon{background-color:transparent;border:0;cursor:pointer;font-size:1rem;padding:.375rem .75rem;position:absolute;right:3px;top:0}.btn-group-vertical .btn.btn-flat:first-of-type,.btn-group-vertical .btn.btn-flat:last-of-type{border-radius:0}.form-control-feedback.fa,.form-control-feedback.fab,.form-control-feedback.far,.form-control-feedback.fas,.form-control-feedback.glyphicon,.form-control-feedback.ion{line-height:calc(2.25rem + 2px)}.form-group-lg .form-control+.form-control-feedback.fa,.form-group-lg .form-control+.form-control-feedback.fab,.form-group-lg .form-control+.form-control-feedback.far,.form-group-lg .form-control+.form-control-feedback.fas,.form-group-lg .form-control+.form-control-feedback.glyphicon,.form-group-lg .form-control+.form-control-feedback.ion,.input-group-lg+.form-control-feedback.fa,.input-group-lg+.form-control-feedback.fab,.input-group-lg+.form-control-feedback.far,.input-group-lg+.form-control-feedback.fas,.input-group-lg+.form-control-feedback.glyphicon,.input-group-lg+.form-control-feedback.ion,.input-lg+.form-control-feedback.fa,.input-lg+.form-control-feedback.fab,.input-lg+.form-control-feedback.far,.input-lg+.form-control-feedback.fas,.input-lg+.form-control-feedback.glyphicon,.input-lg+.form-control-feedback.ion{line-height:calc(2.875rem + 2px)}.form-group-sm .form-control+.form-control-feedback.fa,.form-group-sm .form-control+.form-control-feedback.fab,.form-group-sm .form-control+.form-control-feedback.far,.form-group-sm .form-control+.form-control-feedback.fas,.form-group-sm .form-control+.form-control-feedback.glyphicon,.form-group-sm .form-control+.form-control-feedback.ion,.input-group-sm+.form-control-feedback.fa,.input-group-sm+.form-control-feedback.fab,.input-group-sm+.form-control-feedback.far,.input-group-sm+.form-control-feedback.fas,.input-group-sm+.form-control-feedback.glyphicon,.input-group-sm+.form-control-feedback.ion,.input-sm+.form-control-feedback.fa,.input-sm+.form-control-feedback.fab,.input-sm+.form-control-feedback.far,.input-sm+.form-control-feedback.fas,.input-sm+.form-control-feedback.glyphicon,.input-sm+.form-control-feedback.ion{line-height:calc(1.8125rem + 2px)}label:not(.form-check-label):not(.custom-file-label){font-weight:700}.warning-feedback{font-size:80%;color:#ffc107;display:none;margin-top:.25rem;width:100%}.warning-tooltip{border-radius:.25rem;font-size:.875rem;background-color:rgba(255,193,7,.9);color:#1f2d3d;display:none;line-height:1.5;margin-top:.1rem;max-width:100%;padding:.25rem .5rem;position:absolute;top:100%;z-index:5}.form-control.is-warning{border-color:#ffc107}.form-control.is-warning:focus{border-color:#ffc107;box-shadow:0 0 0 0 rgba(255,193,7,.25)}.form-control.is-warning~.warning-feedback,.form-control.is-warning~.warning-tooltip{display:block}textarea.form-control.is-warning{padding-right:2.25rem;background-position:top calc(.375em + .1875rem) right calc(.375em + .1875rem)}.custom-select.is-warning{border-color:#ffc107}.custom-select.is-warning:focus{border-color:#ffc107;box-shadow:0 0 0 0 rgba(255,193,7,.25)}.custom-select.is-warning~.warning-feedback,.custom-select.is-warning~.warning-tooltip,.form-control-file.is-warning~.warning-feedback,.form-control-file.is-warning~.warning-tooltip{display:block}.form-check-input.is-warning~.form-check-label{color:#ffc107}.form-check-input.is-warning~.warning-feedback,.form-check-input.is-warning~.warning-tooltip{display:block}.custom-control-input.is-warning~.custom-control-label{color:#ffc107}.custom-control-input.is-warning~.custom-control-label:before{border-color:#ffc107}.custom-control-input.is-warning~.warning-feedback,.custom-control-input.is-warning~.warning-tooltip{display:block}.custom-control-input.is-warning:checked~.custom-control-label:before{background-color:#ffce3a;border-color:#ffce3a}.custom-control-input.is-warning:focus~.custom-control-label:before{box-shadow:0 0 0 0 rgba(255,193,7,.25)}.custom-control-input.is-warning:focus:not(:checked)~.custom-control-label:before,.custom-file-input.is-warning~.custom-file-label{border-color:#ffc107}.custom-file-input.is-warning~.warning-feedback,.custom-file-input.is-warning~.warning-tooltip{display:block}.custom-file-input.is-warning:focus~.custom-file-label{border-color:#ffc107;box-shadow:0 0 0 0 rgba(255,193,7,.25)}.custom-switch.custom-switch-off-primary .custom-control-input~.custom-control-label:before{background:#007bff;border-color:#004a99}.custom-switch.custom-switch-off-primary .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-switch.custom-switch-off-primary .custom-control-input~.custom-control-label:after{background:#003e80}.custom-switch.custom-switch-on-primary .custom-control-input:checked~.custom-control-label:before{background:#007bff;border-color:#004a99}.custom-switch.custom-switch-on-primary .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-switch.custom-switch-on-primary .custom-control-input:checked~.custom-control-label:after{background:#99caff}.custom-switch.custom-switch-off-secondary .custom-control-input~.custom-control-label:before{background:#6c757d;border-color:#3d4246}.custom-switch.custom-switch-off-secondary .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-switch.custom-switch-off-secondary .custom-control-input~.custom-control-label:after{background:#313539}.custom-switch.custom-switch-on-secondary .custom-control-input:checked~.custom-control-label:before{background:#6c757d;border-color:#3d4246}.custom-switch.custom-switch-on-secondary .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-switch.custom-switch-on-secondary .custom-control-input:checked~.custom-control-label:after{background:#bcc1c6}.custom-switch.custom-switch-off-success .custom-control-input~.custom-control-label:before{background:#28a745;border-color:#145523}.custom-switch.custom-switch-off-success .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-switch.custom-switch-off-success .custom-control-input~.custom-control-label:after{background:#0f401b}.custom-switch.custom-switch-on-success .custom-control-input:checked~.custom-control-label:before{background:#28a745;border-color:#145523}.custom-switch.custom-switch-on-success .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-switch.custom-switch-on-success .custom-control-input:checked~.custom-control-label:after{background:#86e29b}.custom-switch.custom-switch-off-info .custom-control-input~.custom-control-label:before{background:#17a2b8;border-color:#0c525d}.custom-switch.custom-switch-off-info .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-switch.custom-switch-off-info .custom-control-input~.custom-control-label:after{background:#093e47}.custom-switch.custom-switch-on-info .custom-control-input:checked~.custom-control-label:before{background:#17a2b8;border-color:#0c525d}.custom-switch.custom-switch-on-info .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-switch.custom-switch-on-info .custom-control-input:checked~.custom-control-label:after{background:#7adeee}.custom-switch.custom-switch-off-warning .custom-control-input~.custom-control-label:before{background:#ffc107;border-color:#a07800}.custom-switch.custom-switch-off-warning .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-switch.custom-switch-off-warning .custom-control-input~.custom-control-label:after{background:#876500}.custom-switch.custom-switch-on-warning .custom-control-input:checked~.custom-control-label:before{background:#ffc107;border-color:#a07800}.custom-switch.custom-switch-on-warning .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-switch.custom-switch-on-warning .custom-control-input:checked~.custom-control-label:after{background:#ffe7a0}.custom-switch.custom-switch-off-danger .custom-control-input~.custom-control-label:before{background:#dc3545;border-color:#921925}.custom-switch.custom-switch-off-danger .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-switch.custom-switch-off-danger .custom-control-input~.custom-control-label:after{background:#7c151f}.custom-switch.custom-switch-on-danger .custom-control-input:checked~.custom-control-label:before{background:#dc3545;border-color:#921925}.custom-switch.custom-switch-on-danger .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-switch.custom-switch-on-danger .custom-control-input:checked~.custom-control-label:after{background:#f3b7bd}.custom-switch.custom-switch-off-light .custom-control-input~.custom-control-label:before{background:#f8f9fa;border-color:#bdc6d0}.custom-switch.custom-switch-off-light .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(248,249,250,.25)}.custom-switch.custom-switch-off-light .custom-control-input~.custom-control-label:after{background:#aeb9c5}.custom-switch.custom-switch-on-light .custom-control-input:checked~.custom-control-label:before{background:#f8f9fa;border-color:#bdc6d0}.custom-switch.custom-switch-on-light .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(248,249,250,.25)}.custom-switch.custom-switch-on-light .custom-control-input:checked~.custom-control-label:after{background:#fff}.custom-switch.custom-switch-off-dark .custom-control-input~.custom-control-label:before{background:#343a40;border-color:#060708}.custom-switch.custom-switch-off-dark .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-switch.custom-switch-off-dark .custom-control-input~.custom-control-label:after{background:#000}.custom-switch.custom-switch-on-dark .custom-control-input:checked~.custom-control-label:before{background:#343a40;border-color:#060708}.custom-switch.custom-switch-on-dark .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-switch.custom-switch-on-dark .custom-control-input:checked~.custom-control-label:after{background:#7a8793}.custom-switch.custom-switch-off-lightblue .custom-control-input~.custom-control-label:before{background:#3c8dbc;border-color:#23536f}.custom-switch.custom-switch-off-lightblue .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(60,141,188,.25)}.custom-switch.custom-switch-off-lightblue .custom-control-input~.custom-control-label:after{background:#1d455b}.custom-switch.custom-switch-on-lightblue .custom-control-input:checked~.custom-control-label:before{background:#3c8dbc;border-color:#23536f}.custom-switch.custom-switch-on-lightblue .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(60,141,188,.25)}.custom-switch.custom-switch-on-lightblue .custom-control-input:checked~.custom-control-label:after{background:#acd0e5}.custom-switch.custom-switch-off-navy .custom-control-input~.custom-control-label:before{background:#001f3f;border-color:#000}.custom-switch.custom-switch-off-navy .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,31,63,.25)}.custom-switch.custom-switch-off-navy .custom-control-input~.custom-control-label:after{background:#000}.custom-switch.custom-switch-on-navy .custom-control-input:checked~.custom-control-label:before{background:#001f3f;border-color:#000}.custom-switch.custom-switch-on-navy .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,31,63,.25)}.custom-switch.custom-switch-on-navy .custom-control-input:checked~.custom-control-label:after{background:#006ad8}.custom-switch.custom-switch-off-olive .custom-control-input~.custom-control-label:before{background:#3d9970;border-color:#20503b}.custom-switch.custom-switch-off-olive .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(61,153,112,.25)}.custom-switch.custom-switch-off-olive .custom-control-input~.custom-control-label:after{background:#193e2d}.custom-switch.custom-switch-on-olive .custom-control-input:checked~.custom-control-label:before{background:#3d9970;border-color:#20503b}.custom-switch.custom-switch-on-olive .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(61,153,112,.25)}.custom-switch.custom-switch-on-olive .custom-control-input:checked~.custom-control-label:after{background:#99d6bb}.custom-switch.custom-switch-off-lime .custom-control-input~.custom-control-label:before{background:#01ff70;border-color:#009a43}.custom-switch.custom-switch-off-lime .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(1,255,112,.25)}.custom-switch.custom-switch-off-lime .custom-control-input~.custom-control-label:after{background:#008138}.custom-switch.custom-switch-on-lime .custom-control-input:checked~.custom-control-label:before{background:#01ff70;border-color:#009a43}.custom-switch.custom-switch-on-lime .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(1,255,112,.25)}.custom-switch.custom-switch-on-lime .custom-control-input:checked~.custom-control-label:after{background:#9affc6}.custom-switch.custom-switch-off-fuchsia .custom-control-input~.custom-control-label:before{background:#f012be;border-color:#930974}.custom-switch.custom-switch-off-fuchsia .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(240,18,190,.25)}.custom-switch.custom-switch-off-fuchsia .custom-control-input~.custom-control-label:after{background:#7b0861}.custom-switch.custom-switch-on-fuchsia .custom-control-input:checked~.custom-control-label:before{background:#f012be;border-color:#930974}.custom-switch.custom-switch-on-fuchsia .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(240,18,190,.25)}.custom-switch.custom-switch-on-fuchsia .custom-control-input:checked~.custom-control-label:after{background:#f9a2e5}.custom-switch.custom-switch-off-maroon .custom-control-input~.custom-control-label:before{background:#d81b60;border-color:#7d1038}.custom-switch.custom-switch-off-maroon .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(216,27,96,.25)}.custom-switch.custom-switch-off-maroon .custom-control-input~.custom-control-label:after{background:#670d2e}.custom-switch.custom-switch-on-maroon .custom-control-input:checked~.custom-control-label:before{background:#d81b60;border-color:#7d1038}.custom-switch.custom-switch-on-maroon .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(216,27,96,.25)}.custom-switch.custom-switch-on-maroon .custom-control-input:checked~.custom-control-label:after{background:#f29aba}.custom-switch.custom-switch-off-blue .custom-control-input~.custom-control-label:before{background:#007bff;border-color:#004a99}.custom-switch.custom-switch-off-blue .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-switch.custom-switch-off-blue .custom-control-input~.custom-control-label:after{background:#003e80}.custom-switch.custom-switch-on-blue .custom-control-input:checked~.custom-control-label:before{background:#007bff;border-color:#004a99}.custom-switch.custom-switch-on-blue .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-switch.custom-switch-on-blue .custom-control-input:checked~.custom-control-label:after{background:#99caff}.custom-switch.custom-switch-off-indigo .custom-control-input~.custom-control-label:before{background:#6610f2;border-color:#3d0894}.custom-switch.custom-switch-off-indigo .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(102,16,242,.25)}.custom-switch.custom-switch-off-indigo .custom-control-input~.custom-control-label:after{background:#33077c}.custom-switch.custom-switch-on-indigo .custom-control-input:checked~.custom-control-label:before{background:#6610f2;border-color:#3d0894}.custom-switch.custom-switch-on-indigo .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(102,16,242,.25)}.custom-switch.custom-switch-on-indigo .custom-control-input:checked~.custom-control-label:after{background:#c3a1fa}.custom-switch.custom-switch-off-purple .custom-control-input~.custom-control-label:before{background:#6f42c1;border-color:#432776}.custom-switch.custom-switch-off-purple .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(111,66,193,.25)}.custom-switch.custom-switch-off-purple .custom-control-input~.custom-control-label:after{background:#382063}.custom-switch.custom-switch-on-purple .custom-control-input:checked~.custom-control-label:before{background:#6f42c1;border-color:#432776}.custom-switch.custom-switch-on-purple .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(111,66,193,.25)}.custom-switch.custom-switch-on-purple .custom-control-input:checked~.custom-control-label:after{background:#c7b5e7}.custom-switch.custom-switch-off-pink .custom-control-input~.custom-control-label:before{background:#e83e8c;border-color:#ac145a}.custom-switch.custom-switch-off-pink .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(232,62,140,.25)}.custom-switch.custom-switch-off-pink .custom-control-input~.custom-control-label:after{background:#95124e}.custom-switch.custom-switch-on-pink .custom-control-input:checked~.custom-control-label:before{background:#e83e8c;border-color:#ac145a}.custom-switch.custom-switch-on-pink .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(232,62,140,.25)}.custom-switch.custom-switch-on-pink .custom-control-input:checked~.custom-control-label:after{background:#f8c7dd}.custom-switch.custom-switch-off-red .custom-control-input~.custom-control-label:before{background:#dc3545;border-color:#921925}.custom-switch.custom-switch-off-red .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-switch.custom-switch-off-red .custom-control-input~.custom-control-label:after{background:#7c151f}.custom-switch.custom-switch-on-red .custom-control-input:checked~.custom-control-label:before{background:#dc3545;border-color:#921925}.custom-switch.custom-switch-on-red .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-switch.custom-switch-on-red .custom-control-input:checked~.custom-control-label:after{background:#f3b7bd}.custom-switch.custom-switch-off-orange .custom-control-input~.custom-control-label:before{background:#fd7e14;border-color:#aa4e01}.custom-switch.custom-switch-off-orange .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(253,126,20,.25)}.custom-switch.custom-switch-off-orange .custom-control-input~.custom-control-label:after{background:#904201}.custom-switch.custom-switch-on-orange .custom-control-input:checked~.custom-control-label:before{background:#fd7e14;border-color:#aa4e01}.custom-switch.custom-switch-on-orange .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(253,126,20,.25)}.custom-switch.custom-switch-on-orange .custom-control-input:checked~.custom-control-label:after{background:#fed1ac}.custom-switch.custom-switch-off-yellow .custom-control-input~.custom-control-label:before{background:#ffc107;border-color:#a07800}.custom-switch.custom-switch-off-yellow .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-switch.custom-switch-off-yellow .custom-control-input~.custom-control-label:after{background:#876500}.custom-switch.custom-switch-on-yellow .custom-control-input:checked~.custom-control-label:before{background:#ffc107;border-color:#a07800}.custom-switch.custom-switch-on-yellow .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-switch.custom-switch-on-yellow .custom-control-input:checked~.custom-control-label:after{background:#ffe7a0}.custom-switch.custom-switch-off-green .custom-control-input~.custom-control-label:before{background:#28a745;border-color:#145523}.custom-switch.custom-switch-off-green .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-switch.custom-switch-off-green .custom-control-input~.custom-control-label:after{background:#0f401b}.custom-switch.custom-switch-on-green .custom-control-input:checked~.custom-control-label:before{background:#28a745;border-color:#145523}.custom-switch.custom-switch-on-green .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-switch.custom-switch-on-green .custom-control-input:checked~.custom-control-label:after{background:#86e29b}.custom-switch.custom-switch-off-teal .custom-control-input~.custom-control-label:before{background:#20c997;border-color:#127155}.custom-switch.custom-switch-off-teal .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(32,201,151,.25)}.custom-switch.custom-switch-off-teal .custom-control-input~.custom-control-label:after{background:#0e5b44}.custom-switch.custom-switch-on-teal .custom-control-input:checked~.custom-control-label:before{background:#20c997;border-color:#127155}.custom-switch.custom-switch-on-teal .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(32,201,151,.25)}.custom-switch.custom-switch-on-teal .custom-control-input:checked~.custom-control-label:after{background:#94eed3}.custom-switch.custom-switch-off-cyan .custom-control-input~.custom-control-label:before{background:#17a2b8;border-color:#0c525d}.custom-switch.custom-switch-off-cyan .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-switch.custom-switch-off-cyan .custom-control-input~.custom-control-label:after{background:#093e47}.custom-switch.custom-switch-on-cyan .custom-control-input:checked~.custom-control-label:before{background:#17a2b8;border-color:#0c525d}.custom-switch.custom-switch-on-cyan .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-switch.custom-switch-on-cyan .custom-control-input:checked~.custom-control-label:after{background:#7adeee}.custom-switch.custom-switch-off-white .custom-control-input~.custom-control-label:before{background:#fff;border-color:#ccc}.custom-switch.custom-switch-off-white .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px hsla(0,0%,100%,.25)}.custom-switch.custom-switch-off-white .custom-control-input~.custom-control-label:after{background:#bfbfbf}.custom-switch.custom-switch-on-white .custom-control-input:checked~.custom-control-label:before{background:#fff;border-color:#ccc}.custom-switch.custom-switch-on-white .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px hsla(0,0%,100%,.25)}.custom-switch.custom-switch-on-white .custom-control-input:checked~.custom-control-label:after{background:#fff}.custom-switch.custom-switch-off-gray .custom-control-input~.custom-control-label:before{background:#6c757d;border-color:#3d4246}.custom-switch.custom-switch-off-gray .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-switch.custom-switch-off-gray .custom-control-input~.custom-control-label:after{background:#313539}.custom-switch.custom-switch-on-gray .custom-control-input:checked~.custom-control-label:before{background:#6c757d;border-color:#3d4246}.custom-switch.custom-switch-on-gray .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-switch.custom-switch-on-gray .custom-control-input:checked~.custom-control-label:after{background:#bcc1c6}.custom-switch.custom-switch-off-gray-dark .custom-control-input~.custom-control-label:before{background:#343a40;border-color:#060708}.custom-switch.custom-switch-off-gray-dark .custom-control-input:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-switch.custom-switch-off-gray-dark .custom-control-input~.custom-control-label:after{background:#000}.custom-switch.custom-switch-on-gray-dark .custom-control-input:checked~.custom-control-label:before{background:#343a40;border-color:#060708}.custom-switch.custom-switch-on-gray-dark .custom-control-input:checked:focus~.custom-control-label:before{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-switch.custom-switch-on-gray-dark .custom-control-input:checked~.custom-control-label:after{background:#7a8793}.custom-range.custom-range-primary:focus{outline:none}.custom-range.custom-range-primary:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-range.custom-range-primary:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-range.custom-range-primary:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-range.custom-range-primary::-webkit-slider-thumb{background-color:#007bff}.custom-range.custom-range-primary::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range.custom-range-primary::-moz-range-thumb{background-color:#007bff}.custom-range.custom-range-primary::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range.custom-range-primary::-ms-thumb{background-color:#007bff}.custom-range.custom-range-primary::-ms-thumb:active{background-color:#b3d7ff}.custom-range.custom-range-secondary:focus{outline:none}.custom-range.custom-range-secondary:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-range.custom-range-secondary:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-range.custom-range-secondary:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-range.custom-range-secondary::-webkit-slider-thumb{background-color:#6c757d}.custom-range.custom-range-secondary::-webkit-slider-thumb:active{background-color:#caced1}.custom-range.custom-range-secondary::-moz-range-thumb{background-color:#6c757d}.custom-range.custom-range-secondary::-moz-range-thumb:active{background-color:#caced1}.custom-range.custom-range-secondary::-ms-thumb{background-color:#6c757d}.custom-range.custom-range-secondary::-ms-thumb:active{background-color:#caced1}.custom-range.custom-range-success:focus{outline:none}.custom-range.custom-range-success:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-range.custom-range-success:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-range.custom-range-success:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-range.custom-range-success::-webkit-slider-thumb{background-color:#28a745}.custom-range.custom-range-success::-webkit-slider-thumb:active{background-color:#9be7ac}.custom-range.custom-range-success::-moz-range-thumb{background-color:#28a745}.custom-range.custom-range-success::-moz-range-thumb:active{background-color:#9be7ac}.custom-range.custom-range-success::-ms-thumb{background-color:#28a745}.custom-range.custom-range-success::-ms-thumb:active{background-color:#9be7ac}.custom-range.custom-range-info:focus{outline:none}.custom-range.custom-range-info:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-range.custom-range-info:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-range.custom-range-info:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-range.custom-range-info::-webkit-slider-thumb{background-color:#17a2b8}.custom-range.custom-range-info::-webkit-slider-thumb:active{background-color:#90e4f1}.custom-range.custom-range-info::-moz-range-thumb{background-color:#17a2b8}.custom-range.custom-range-info::-moz-range-thumb:active{background-color:#90e4f1}.custom-range.custom-range-info::-ms-thumb{background-color:#17a2b8}.custom-range.custom-range-info::-ms-thumb:active{background-color:#90e4f1}.custom-range.custom-range-warning:focus{outline:none}.custom-range.custom-range-warning:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-range.custom-range-warning:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-range.custom-range-warning:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-range.custom-range-warning::-webkit-slider-thumb{background-color:#ffc107}.custom-range.custom-range-warning::-webkit-slider-thumb:active{background-color:#ffeeba}.custom-range.custom-range-warning::-moz-range-thumb{background-color:#ffc107}.custom-range.custom-range-warning::-moz-range-thumb:active{background-color:#ffeeba}.custom-range.custom-range-warning::-ms-thumb{background-color:#ffc107}.custom-range.custom-range-warning::-ms-thumb:active{background-color:#ffeeba}.custom-range.custom-range-danger:focus{outline:none}.custom-range.custom-range-danger:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-range.custom-range-danger:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-range.custom-range-danger:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-range.custom-range-danger::-webkit-slider-thumb{background-color:#dc3545}.custom-range.custom-range-danger::-webkit-slider-thumb:active{background-color:#f6cdd1}.custom-range.custom-range-danger::-moz-range-thumb{background-color:#dc3545}.custom-range.custom-range-danger::-moz-range-thumb:active{background-color:#f6cdd1}.custom-range.custom-range-danger::-ms-thumb{background-color:#dc3545}.custom-range.custom-range-danger::-ms-thumb:active{background-color:#f6cdd1}.custom-range.custom-range-light:focus{outline:none}.custom-range.custom-range-light:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(248,249,250,.25)}.custom-range.custom-range-light:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(248,249,250,.25)}.custom-range.custom-range-light:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(248,249,250,.25)}.custom-range.custom-range-light::-webkit-slider-thumb{background-color:#f8f9fa}.custom-range.custom-range-light::-webkit-slider-thumb:active{background-color:#fff}.custom-range.custom-range-light::-moz-range-thumb{background-color:#f8f9fa}.custom-range.custom-range-light::-moz-range-thumb:active{background-color:#fff}.custom-range.custom-range-light::-ms-thumb{background-color:#f8f9fa}.custom-range.custom-range-light::-ms-thumb:active{background-color:#fff}.custom-range.custom-range-dark:focus{outline:none}.custom-range.custom-range-dark:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-range.custom-range-dark:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-range.custom-range-dark:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-range.custom-range-dark::-webkit-slider-thumb{background-color:#343a40}.custom-range.custom-range-dark::-webkit-slider-thumb:active{background-color:#88939e}.custom-range.custom-range-dark::-moz-range-thumb{background-color:#343a40}.custom-range.custom-range-dark::-moz-range-thumb:active{background-color:#88939e}.custom-range.custom-range-dark::-ms-thumb{background-color:#343a40}.custom-range.custom-range-dark::-ms-thumb:active{background-color:#88939e}.custom-range.custom-range-lightblue:focus{outline:none}.custom-range.custom-range-lightblue:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(60,141,188,.25)}.custom-range.custom-range-lightblue:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(60,141,188,.25)}.custom-range.custom-range-lightblue:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(60,141,188,.25)}.custom-range.custom-range-lightblue::-webkit-slider-thumb{background-color:#3c8dbc}.custom-range.custom-range-lightblue::-webkit-slider-thumb:active{background-color:#c0dbeb}.custom-range.custom-range-lightblue::-moz-range-thumb{background-color:#3c8dbc}.custom-range.custom-range-lightblue::-moz-range-thumb:active{background-color:#c0dbeb}.custom-range.custom-range-lightblue::-ms-thumb{background-color:#3c8dbc}.custom-range.custom-range-lightblue::-ms-thumb:active{background-color:#c0dbeb}.custom-range.custom-range-navy:focus{outline:none}.custom-range.custom-range-navy:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,31,63,.25)}.custom-range.custom-range-navy:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,31,63,.25)}.custom-range.custom-range-navy:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,31,63,.25)}.custom-range.custom-range-navy::-webkit-slider-thumb{background-color:#001f3f}.custom-range.custom-range-navy::-webkit-slider-thumb:active{background-color:#0077f2}.custom-range.custom-range-navy::-moz-range-thumb{background-color:#001f3f}.custom-range.custom-range-navy::-moz-range-thumb:active{background-color:#0077f2}.custom-range.custom-range-navy::-ms-thumb{background-color:#001f3f}.custom-range.custom-range-navy::-ms-thumb:active{background-color:#0077f2}.custom-range.custom-range-olive:focus{outline:none}.custom-range.custom-range-olive:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(61,153,112,.25)}.custom-range.custom-range-olive:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(61,153,112,.25)}.custom-range.custom-range-olive:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(61,153,112,.25)}.custom-range.custom-range-olive::-webkit-slider-thumb{background-color:#3d9970}.custom-range.custom-range-olive::-webkit-slider-thumb:active{background-color:#abdec7}.custom-range.custom-range-olive::-moz-range-thumb{background-color:#3d9970}.custom-range.custom-range-olive::-moz-range-thumb:active{background-color:#abdec7}.custom-range.custom-range-olive::-ms-thumb{background-color:#3d9970}.custom-range.custom-range-olive::-ms-thumb:active{background-color:#abdec7}.custom-range.custom-range-lime:focus{outline:none}.custom-range.custom-range-lime:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(1,255,112,.25)}.custom-range.custom-range-lime:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(1,255,112,.25)}.custom-range.custom-range-lime:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(1,255,112,.25)}.custom-range.custom-range-lime::-webkit-slider-thumb{background-color:#01ff70}.custom-range.custom-range-lime::-webkit-slider-thumb:active{background-color:#b4ffd4}.custom-range.custom-range-lime::-moz-range-thumb{background-color:#01ff70}.custom-range.custom-range-lime::-moz-range-thumb:active{background-color:#b4ffd4}.custom-range.custom-range-lime::-ms-thumb{background-color:#01ff70}.custom-range.custom-range-lime::-ms-thumb:active{background-color:#b4ffd4}.custom-range.custom-range-fuchsia:focus{outline:none}.custom-range.custom-range-fuchsia:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(240,18,190,.25)}.custom-range.custom-range-fuchsia:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(240,18,190,.25)}.custom-range.custom-range-fuchsia:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(240,18,190,.25)}.custom-range.custom-range-fuchsia::-webkit-slider-thumb{background-color:#f012be}.custom-range.custom-range-fuchsia::-webkit-slider-thumb:active{background-color:#fbbaec}.custom-range.custom-range-fuchsia::-moz-range-thumb{background-color:#f012be}.custom-range.custom-range-fuchsia::-moz-range-thumb:active{background-color:#fbbaec}.custom-range.custom-range-fuchsia::-ms-thumb{background-color:#f012be}.custom-range.custom-range-fuchsia::-ms-thumb:active{background-color:#fbbaec}.custom-range.custom-range-maroon:focus{outline:none}.custom-range.custom-range-maroon:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(216,27,96,.25)}.custom-range.custom-range-maroon:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(216,27,96,.25)}.custom-range.custom-range-maroon:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(216,27,96,.25)}.custom-range.custom-range-maroon::-webkit-slider-thumb{background-color:#d81b60}.custom-range.custom-range-maroon::-webkit-slider-thumb:active{background-color:#f5b0c9}.custom-range.custom-range-maroon::-moz-range-thumb{background-color:#d81b60}.custom-range.custom-range-maroon::-moz-range-thumb:active{background-color:#f5b0c9}.custom-range.custom-range-maroon::-ms-thumb{background-color:#d81b60}.custom-range.custom-range-maroon::-ms-thumb:active{background-color:#f5b0c9}.custom-range.custom-range-blue:focus{outline:none}.custom-range.custom-range-blue:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-range.custom-range-blue:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-range.custom-range-blue:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(0,123,255,.25)}.custom-range.custom-range-blue::-webkit-slider-thumb{background-color:#007bff}.custom-range.custom-range-blue::-webkit-slider-thumb:active{background-color:#b3d7ff}.custom-range.custom-range-blue::-moz-range-thumb{background-color:#007bff}.custom-range.custom-range-blue::-moz-range-thumb:active{background-color:#b3d7ff}.custom-range.custom-range-blue::-ms-thumb{background-color:#007bff}.custom-range.custom-range-blue::-ms-thumb:active{background-color:#b3d7ff}.custom-range.custom-range-indigo:focus{outline:none}.custom-range.custom-range-indigo:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(102,16,242,.25)}.custom-range.custom-range-indigo:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(102,16,242,.25)}.custom-range.custom-range-indigo:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(102,16,242,.25)}.custom-range.custom-range-indigo::-webkit-slider-thumb{background-color:#6610f2}.custom-range.custom-range-indigo::-webkit-slider-thumb:active{background-color:#d2b9fb}.custom-range.custom-range-indigo::-moz-range-thumb{background-color:#6610f2}.custom-range.custom-range-indigo::-moz-range-thumb:active{background-color:#d2b9fb}.custom-range.custom-range-indigo::-ms-thumb{background-color:#6610f2}.custom-range.custom-range-indigo::-ms-thumb:active{background-color:#d2b9fb}.custom-range.custom-range-purple:focus{outline:none}.custom-range.custom-range-purple:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(111,66,193,.25)}.custom-range.custom-range-purple:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(111,66,193,.25)}.custom-range.custom-range-purple:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(111,66,193,.25)}.custom-range.custom-range-purple::-webkit-slider-thumb{background-color:#6f42c1}.custom-range.custom-range-purple::-webkit-slider-thumb:active{background-color:#d5c8ed}.custom-range.custom-range-purple::-moz-range-thumb{background-color:#6f42c1}.custom-range.custom-range-purple::-moz-range-thumb:active{background-color:#d5c8ed}.custom-range.custom-range-purple::-ms-thumb{background-color:#6f42c1}.custom-range.custom-range-purple::-ms-thumb:active{background-color:#d5c8ed}.custom-range.custom-range-pink:focus{outline:none}.custom-range.custom-range-pink:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(232,62,140,.25)}.custom-range.custom-range-pink:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(232,62,140,.25)}.custom-range.custom-range-pink:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(232,62,140,.25)}.custom-range.custom-range-pink::-webkit-slider-thumb{background-color:#e83e8c}.custom-range.custom-range-pink::-webkit-slider-thumb:active{background-color:#fbddeb}.custom-range.custom-range-pink::-moz-range-thumb{background-color:#e83e8c}.custom-range.custom-range-pink::-moz-range-thumb:active{background-color:#fbddeb}.custom-range.custom-range-pink::-ms-thumb{background-color:#e83e8c}.custom-range.custom-range-pink::-ms-thumb:active{background-color:#fbddeb}.custom-range.custom-range-red:focus{outline:none}.custom-range.custom-range-red:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-range.custom-range-red:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-range.custom-range-red:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(220,53,69,.25)}.custom-range.custom-range-red::-webkit-slider-thumb{background-color:#dc3545}.custom-range.custom-range-red::-webkit-slider-thumb:active{background-color:#f6cdd1}.custom-range.custom-range-red::-moz-range-thumb{background-color:#dc3545}.custom-range.custom-range-red::-moz-range-thumb:active{background-color:#f6cdd1}.custom-range.custom-range-red::-ms-thumb{background-color:#dc3545}.custom-range.custom-range-red::-ms-thumb:active{background-color:#f6cdd1}.custom-range.custom-range-orange:focus{outline:none}.custom-range.custom-range-orange:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(253,126,20,.25)}.custom-range.custom-range-orange:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(253,126,20,.25)}.custom-range.custom-range-orange:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(253,126,20,.25)}.custom-range.custom-range-orange::-webkit-slider-thumb{background-color:#fd7e14}.custom-range.custom-range-orange::-webkit-slider-thumb:active{background-color:#ffdfc5}.custom-range.custom-range-orange::-moz-range-thumb{background-color:#fd7e14}.custom-range.custom-range-orange::-moz-range-thumb:active{background-color:#ffdfc5}.custom-range.custom-range-orange::-ms-thumb{background-color:#fd7e14}.custom-range.custom-range-orange::-ms-thumb:active{background-color:#ffdfc5}.custom-range.custom-range-yellow:focus{outline:none}.custom-range.custom-range-yellow:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-range.custom-range-yellow:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-range.custom-range-yellow:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(255,193,7,.25)}.custom-range.custom-range-yellow::-webkit-slider-thumb{background-color:#ffc107}.custom-range.custom-range-yellow::-webkit-slider-thumb:active{background-color:#ffeeba}.custom-range.custom-range-yellow::-moz-range-thumb{background-color:#ffc107}.custom-range.custom-range-yellow::-moz-range-thumb:active{background-color:#ffeeba}.custom-range.custom-range-yellow::-ms-thumb{background-color:#ffc107}.custom-range.custom-range-yellow::-ms-thumb:active{background-color:#ffeeba}.custom-range.custom-range-green:focus{outline:none}.custom-range.custom-range-green:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-range.custom-range-green:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-range.custom-range-green:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(40,167,69,.25)}.custom-range.custom-range-green::-webkit-slider-thumb{background-color:#28a745}.custom-range.custom-range-green::-webkit-slider-thumb:active{background-color:#9be7ac}.custom-range.custom-range-green::-moz-range-thumb{background-color:#28a745}.custom-range.custom-range-green::-moz-range-thumb:active{background-color:#9be7ac}.custom-range.custom-range-green::-ms-thumb{background-color:#28a745}.custom-range.custom-range-green::-ms-thumb:active{background-color:#9be7ac}.custom-range.custom-range-teal:focus{outline:none}.custom-range.custom-range-teal:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(32,201,151,.25)}.custom-range.custom-range-teal:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(32,201,151,.25)}.custom-range.custom-range-teal:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(32,201,151,.25)}.custom-range.custom-range-teal::-webkit-slider-thumb{background-color:#20c997}.custom-range.custom-range-teal::-webkit-slider-thumb:active{background-color:#aaf1dc}.custom-range.custom-range-teal::-moz-range-thumb{background-color:#20c997}.custom-range.custom-range-teal::-moz-range-thumb:active{background-color:#aaf1dc}.custom-range.custom-range-teal::-ms-thumb{background-color:#20c997}.custom-range.custom-range-teal::-ms-thumb:active{background-color:#aaf1dc}.custom-range.custom-range-cyan:focus{outline:none}.custom-range.custom-range-cyan:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-range.custom-range-cyan:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-range.custom-range-cyan:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(23,162,184,.25)}.custom-range.custom-range-cyan::-webkit-slider-thumb{background-color:#17a2b8}.custom-range.custom-range-cyan::-webkit-slider-thumb:active{background-color:#90e4f1}.custom-range.custom-range-cyan::-moz-range-thumb{background-color:#17a2b8}.custom-range.custom-range-cyan::-moz-range-thumb:active{background-color:#90e4f1}.custom-range.custom-range-cyan::-ms-thumb{background-color:#17a2b8}.custom-range.custom-range-cyan::-ms-thumb:active{background-color:#90e4f1}.custom-range.custom-range-white:focus{outline:none}.custom-range.custom-range-white:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px hsla(0,0%,100%,.25)}.custom-range.custom-range-white:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px hsla(0,0%,100%,.25)}.custom-range.custom-range-white:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px hsla(0,0%,100%,.25)}.custom-range.custom-range-white::-webkit-slider-thumb,.custom-range.custom-range-white::-webkit-slider-thumb:active{background-color:#fff}.custom-range.custom-range-white::-moz-range-thumb,.custom-range.custom-range-white::-moz-range-thumb:active{background-color:#fff}.custom-range.custom-range-white::-ms-thumb,.custom-range.custom-range-white::-ms-thumb:active{background-color:#fff}.custom-range.custom-range-gray:focus{outline:none}.custom-range.custom-range-gray:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-range.custom-range-gray:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-range.custom-range-gray:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(108,117,125,.25)}.custom-range.custom-range-gray::-webkit-slider-thumb{background-color:#6c757d}.custom-range.custom-range-gray::-webkit-slider-thumb:active{background-color:#caced1}.custom-range.custom-range-gray::-moz-range-thumb{background-color:#6c757d}.custom-range.custom-range-gray::-moz-range-thumb:active{background-color:#caced1}.custom-range.custom-range-gray::-ms-thumb{background-color:#6c757d}.custom-range.custom-range-gray::-ms-thumb:active{background-color:#caced1}.custom-range.custom-range-gray-dark:focus{outline:none}.custom-range.custom-range-gray-dark:focus::-webkit-slider-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-range.custom-range-gray-dark:focus::-moz-range-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-range.custom-range-gray-dark:focus::-ms-thumb{box-shadow:0 0 0 1px #fff,0 0 0 2px rgba(52,58,64,.25)}.custom-range.custom-range-gray-dark::-webkit-slider-thumb{background-color:#343a40}.custom-range.custom-range-gray-dark::-webkit-slider-thumb:active{background-color:#88939e}.custom-range.custom-range-gray-dark::-moz-range-thumb{background-color:#343a40}.custom-range.custom-range-gray-dark::-moz-range-thumb:active{background-color:#88939e}.custom-range.custom-range-gray-dark::-ms-thumb{background-color:#343a40}.custom-range.custom-range-gray-dark::-ms-thumb:active{background-color:#88939e}.progress{box-shadow:none;border-radius:1px}.progress.vertical{display:inline-block;height:200px;margin-right:10px;position:relative;width:30px}.progress.vertical>.progress-bar{bottom:0;position:absolute;width:100%}.progress.vertical.progress-sm,.progress.vertical.sm{width:20px}.progress.vertical.progress-xs,.progress.vertical.xs{width:10px}.progress.vertical.progress-xxs,.progress.vertical.xxs{width:3px}.progress-group{margin-bottom:.5rem}.progress-sm{height:10px}.progress-xs{height:7px}.progress-xxs{height:3px}.table tr>td .progress{margin:0}.card-primary:not(.card-outline)>.card-header{background-color:#007bff}.card-primary:not(.card-outline)>.card-header,.card-primary:not(.card-outline)>.card-header a{color:#fff}.card-primary:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-primary.card-outline{border-top:3px solid #007bff}.card-primary.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-primary.card-outline-tabs>.card-header a.active{border-top:3px solid #007bff}.bg-gradient-primary .btn-tool,.bg-primary .btn-tool,.card-primary:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-primary .btn-tool:hover,.bg-primary .btn-tool:hover,.card-primary:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-primary .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-primary .bootstrap-datetimepicker-widget .table th,.card.bg-primary .bootstrap-datetimepicker-widget .table td,.card.bg-primary .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-primary .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-primary .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-primary .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-primary .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-primary .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-primary .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-primary .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-primary .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-primary .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-primary .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#0067d6;color:#fff}.card.bg-gradient-primary .bootstrap-datetimepicker-widget table td.today:before,.card.bg-primary .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-primary .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-primary .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-primary .bootstrap-datetimepicker-widget table td.active,.card.bg-primary .bootstrap-datetimepicker-widget table td.active:hover{background:#3395ff;color:#fff}.card-secondary:not(.card-outline)>.card-header{background-color:#6c757d}.card-secondary:not(.card-outline)>.card-header,.card-secondary:not(.card-outline)>.card-header a{color:#fff}.card-secondary:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-secondary.card-outline{border-top:3px solid #6c757d}.card-secondary.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-secondary.card-outline-tabs>.card-header a.active{border-top:3px solid #6c757d}.bg-gradient-secondary .btn-tool,.bg-secondary .btn-tool,.card-secondary:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-secondary .btn-tool:hover,.bg-secondary .btn-tool:hover,.card-secondary:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-secondary .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-secondary .bootstrap-datetimepicker-widget .table th,.card.bg-secondary .bootstrap-datetimepicker-widget .table td,.card.bg-secondary .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-secondary .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-secondary .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-secondary .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-secondary .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-secondary .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#596167;color:#fff}.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table td.today:before,.card.bg-secondary .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-secondary .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-secondary .bootstrap-datetimepicker-widget table td.active,.card.bg-secondary .bootstrap-datetimepicker-widget table td.active:hover{background:#868e96;color:#fff}.card-success:not(.card-outline)>.card-header{background-color:#28a745}.card-success:not(.card-outline)>.card-header,.card-success:not(.card-outline)>.card-header a{color:#fff}.card-success:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-success.card-outline{border-top:3px solid #28a745}.card-success.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-success.card-outline-tabs>.card-header a.active{border-top:3px solid #28a745}.bg-gradient-success .btn-tool,.bg-success .btn-tool,.card-success:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-success .btn-tool:hover,.bg-success .btn-tool:hover,.card-success:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-success .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-success .bootstrap-datetimepicker-widget .table th,.card.bg-success .bootstrap-datetimepicker-widget .table td,.card.bg-success .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-success .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-success .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-success .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-success .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-success .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-success .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-success .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-success .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-success .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-success .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#208637;color:#fff}.card.bg-gradient-success .bootstrap-datetimepicker-widget table td.today:before,.card.bg-success .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-success .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-success .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-success .bootstrap-datetimepicker-widget table td.active,.card.bg-success .bootstrap-datetimepicker-widget table td.active:hover{background:#34ce57;color:#fff}.card-info:not(.card-outline)>.card-header{background-color:#17a2b8}.card-info:not(.card-outline)>.card-header,.card-info:not(.card-outline)>.card-header a{color:#fff}.card-info:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-info.card-outline{border-top:3px solid #17a2b8}.card-info.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-info.card-outline-tabs>.card-header a.active{border-top:3px solid #17a2b8}.bg-gradient-info .btn-tool,.bg-info .btn-tool,.card-info:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-info .btn-tool:hover,.bg-info .btn-tool:hover,.card-info:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-info .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-info .bootstrap-datetimepicker-widget .table th,.card.bg-info .bootstrap-datetimepicker-widget .table td,.card.bg-info .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-info .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-info .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-info .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-info .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-info .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-info .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-info .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-info .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-info .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-info .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#128294;color:#fff}.card.bg-gradient-info .bootstrap-datetimepicker-widget table td.today:before,.card.bg-info .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-info .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-info .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-info .bootstrap-datetimepicker-widget table td.active,.card.bg-info .bootstrap-datetimepicker-widget table td.active:hover{background:#1fc8e3;color:#fff}.card-warning:not(.card-outline)>.card-header{background-color:#ffc107}.card-warning:not(.card-outline)>.card-header,.card-warning:not(.card-outline)>.card-header a,.card-warning:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-warning.card-outline{border-top:3px solid #ffc107}.card-warning.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-warning.card-outline-tabs>.card-header a.active{border-top:3px solid #ffc107}.bg-gradient-warning .btn-tool,.bg-warning .btn-tool,.card-warning:not(.card-outline) .btn-tool{color:rgba(31,45,61,.8)}.bg-gradient-warning .btn-tool:hover,.bg-warning .btn-tool:hover,.card-warning:not(.card-outline) .btn-tool:hover{color:#1f2d3d}.card.bg-gradient-warning .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-warning .bootstrap-datetimepicker-widget .table th,.card.bg-warning .bootstrap-datetimepicker-widget .table td,.card.bg-warning .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-warning .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-warning .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-warning .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-warning .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-warning .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-warning .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-warning .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-warning .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-warning .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-warning .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#dda600;color:#1f2d3d}.card.bg-gradient-warning .bootstrap-datetimepicker-widget table td.today:before,.card.bg-warning .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#1f2d3d}.card.bg-gradient-warning .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-warning .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-warning .bootstrap-datetimepicker-widget table td.active,.card.bg-warning .bootstrap-datetimepicker-widget table td.active:hover{background:#ffce3a;color:#1f2d3d}.card-danger:not(.card-outline)>.card-header{background-color:#dc3545}.card-danger:not(.card-outline)>.card-header,.card-danger:not(.card-outline)>.card-header a{color:#fff}.card-danger:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-danger.card-outline{border-top:3px solid #dc3545}.card-danger.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-danger.card-outline-tabs>.card-header a.active{border-top:3px solid #dc3545}.bg-danger .btn-tool,.bg-gradient-danger .btn-tool,.card-danger:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-danger .btn-tool:hover,.bg-gradient-danger .btn-tool:hover,.card-danger:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-danger .bootstrap-datetimepicker-widget .table td,.card.bg-danger .bootstrap-datetimepicker-widget .table th,.card.bg-gradient-danger .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-danger .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-danger .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-danger .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-danger .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-danger .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-danger .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#c62232;color:#fff}.card.bg-danger .bootstrap-datetimepicker-widget table td.today:before,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-danger .bootstrap-datetimepicker-widget table td.active,.card.bg-danger .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-danger .bootstrap-datetimepicker-widget table td.active:hover{background:#e4606d;color:#fff}.card-light:not(.card-outline)>.card-header{background-color:#f8f9fa}.card-light:not(.card-outline)>.card-header,.card-light:not(.card-outline)>.card-header a,.card-light:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-light.card-outline{border-top:3px solid #f8f9fa}.card-light.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-light.card-outline-tabs>.card-header a.active{border-top:3px solid #f8f9fa}.bg-gradient-light .btn-tool,.bg-light .btn-tool,.card-light:not(.card-outline) .btn-tool{color:rgba(31,45,61,.8)}.bg-gradient-light .btn-tool:hover,.bg-light .btn-tool:hover,.card-light:not(.card-outline) .btn-tool:hover{color:#1f2d3d}.card.bg-gradient-light .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-light .bootstrap-datetimepicker-widget .table th,.card.bg-light .bootstrap-datetimepicker-widget .table td,.card.bg-light .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-light .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-light .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-light .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-light .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-light .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-light .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-light .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-light .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-light .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-light .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#e0e5e9;color:#1f2d3d}.card.bg-gradient-light .bootstrap-datetimepicker-widget table td.today:before,.card.bg-light .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#1f2d3d}.card.bg-gradient-light .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-light .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-light .bootstrap-datetimepicker-widget table td.active,.card.bg-light .bootstrap-datetimepicker-widget table td.active:hover{background:#fff;color:#1f2d3d}.card-dark:not(.card-outline)>.card-header{background-color:#343a40}.card-dark:not(.card-outline)>.card-header,.card-dark:not(.card-outline)>.card-header a{color:#fff}.card-dark:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-dark.card-outline{border-top:3px solid #343a40}.card-dark.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-dark.card-outline-tabs>.card-header a.active{border-top:3px solid #343a40}.bg-dark .btn-tool,.bg-gradient-dark .btn-tool,.card-dark:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-dark .btn-tool:hover,.bg-gradient-dark .btn-tool:hover,.card-dark:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-dark .bootstrap-datetimepicker-widget .table td,.card.bg-dark .bootstrap-datetimepicker-widget .table th,.card.bg-gradient-dark .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-dark .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-dark .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-dark .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-dark .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-dark .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-dark .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#222629;color:#fff}.card.bg-dark .bootstrap-datetimepicker-widget table td.today:before,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-dark .bootstrap-datetimepicker-widget table td.active,.card.bg-dark .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-dark .bootstrap-datetimepicker-widget table td.active:hover{background:#4b545c;color:#fff}.card-lightblue:not(.card-outline)>.card-header{background-color:#3c8dbc}.card-lightblue:not(.card-outline)>.card-header,.card-lightblue:not(.card-outline)>.card-header a{color:#fff}.card-lightblue:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-lightblue.card-outline{border-top:3px solid #3c8dbc}.card-lightblue.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-lightblue.card-outline-tabs>.card-header a.active{border-top:3px solid #3c8dbc}.bg-gradient-lightblue .btn-tool,.bg-lightblue .btn-tool,.card-lightblue:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-lightblue .btn-tool:hover,.bg-lightblue .btn-tool:hover,.card-lightblue:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget .table th,.card.bg-lightblue .bootstrap-datetimepicker-widget .table td,.card.bg-lightblue .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-lightblue .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-lightblue .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-lightblue .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-lightblue .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-lightblue .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#32769d;color:#fff}.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table td.today:before,.card.bg-lightblue .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-lightblue .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-lightblue .bootstrap-datetimepicker-widget table td.active,.card.bg-lightblue .bootstrap-datetimepicker-widget table td.active:hover{background:#5fa4cc;color:#fff}.card-navy:not(.card-outline)>.card-header{background-color:#001f3f}.card-navy:not(.card-outline)>.card-header,.card-navy:not(.card-outline)>.card-header a{color:#fff}.card-navy:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-navy.card-outline{border-top:3px solid #001f3f}.card-navy.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-navy.card-outline-tabs>.card-header a.active{border-top:3px solid #001f3f}.bg-gradient-navy .btn-tool,.bg-navy .btn-tool,.card-navy:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-navy .btn-tool:hover,.bg-navy .btn-tool:hover,.card-navy:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-navy .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-navy .bootstrap-datetimepicker-widget .table th,.card.bg-navy .bootstrap-datetimepicker-widget .table td,.card.bg-navy .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-navy .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-navy .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-navy .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-navy .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-navy .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-navy .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-navy .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-navy .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-navy .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-navy .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#000b16;color:#fff}.card.bg-gradient-navy .bootstrap-datetimepicker-widget table td.today:before,.card.bg-navy .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-navy .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-navy .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-navy .bootstrap-datetimepicker-widget table td.active,.card.bg-navy .bootstrap-datetimepicker-widget table td.active:hover{background:#003872;color:#fff}.card-olive:not(.card-outline)>.card-header{background-color:#3d9970}.card-olive:not(.card-outline)>.card-header,.card-olive:not(.card-outline)>.card-header a{color:#fff}.card-olive:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-olive.card-outline{border-top:3px solid #3d9970}.card-olive.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-olive.card-outline-tabs>.card-header a.active{border-top:3px solid #3d9970}.bg-gradient-olive .btn-tool,.bg-olive .btn-tool,.card-olive:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-olive .btn-tool:hover,.bg-olive .btn-tool:hover,.card-olive:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-olive .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-olive .bootstrap-datetimepicker-widget .table th,.card.bg-olive .bootstrap-datetimepicker-widget .table td,.card.bg-olive .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-olive .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-olive .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-olive .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-olive .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-olive .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-olive .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-olive .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-olive .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-olive .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-olive .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#317c5b;color:#fff}.card.bg-gradient-olive .bootstrap-datetimepicker-widget table td.today:before,.card.bg-olive .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-olive .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-olive .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-olive .bootstrap-datetimepicker-widget table td.active,.card.bg-olive .bootstrap-datetimepicker-widget table td.active:hover{background:#50b98a;color:#fff}.card-lime:not(.card-outline)>.card-header{background-color:#01ff70}.card-lime:not(.card-outline)>.card-header,.card-lime:not(.card-outline)>.card-header a,.card-lime:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-lime.card-outline{border-top:3px solid #01ff70}.card-lime.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-lime.card-outline-tabs>.card-header a.active{border-top:3px solid #01ff70}.bg-gradient-lime .btn-tool,.bg-lime .btn-tool,.card-lime:not(.card-outline) .btn-tool{color:rgba(31,45,61,.8)}.bg-gradient-lime .btn-tool:hover,.bg-lime .btn-tool:hover,.card-lime:not(.card-outline) .btn-tool:hover{color:#1f2d3d}.card.bg-gradient-lime .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-lime .bootstrap-datetimepicker-widget .table th,.card.bg-lime .bootstrap-datetimepicker-widget .table td,.card.bg-lime .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-lime .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-lime .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-lime .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-lime .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-lime .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-lime .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-lime .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-lime .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-lime .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-lime .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#00d75e;color:#1f2d3d}.card.bg-gradient-lime .bootstrap-datetimepicker-widget table td.today:before,.card.bg-lime .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#1f2d3d}.card.bg-gradient-lime .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-lime .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-lime .bootstrap-datetimepicker-widget table td.active,.card.bg-lime .bootstrap-datetimepicker-widget table td.active:hover{background:#34ff8d;color:#1f2d3d}.card-fuchsia:not(.card-outline)>.card-header{background-color:#f012be}.card-fuchsia:not(.card-outline)>.card-header,.card-fuchsia:not(.card-outline)>.card-header a{color:#fff}.card-fuchsia:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-fuchsia.card-outline{border-top:3px solid #f012be}.card-fuchsia.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-fuchsia.card-outline-tabs>.card-header a.active{border-top:3px solid #f012be}.bg-fuchsia .btn-tool,.bg-gradient-fuchsia .btn-tool,.card-fuchsia:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-fuchsia .btn-tool:hover,.bg-gradient-fuchsia .btn-tool:hover,.card-fuchsia:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-fuchsia .bootstrap-datetimepicker-widget .table td,.card.bg-fuchsia .bootstrap-datetimepicker-widget .table th,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-fuchsia .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-fuchsia .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-fuchsia .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-fuchsia .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-fuchsia .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#cc0da1;color:#fff}.card.bg-fuchsia .bootstrap-datetimepicker-widget table td.today:before,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-fuchsia .bootstrap-datetimepicker-widget table td.active,.card.bg-fuchsia .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-fuchsia .bootstrap-datetimepicker-widget table td.active:hover{background:#f342cb;color:#fff}.card-maroon:not(.card-outline)>.card-header{background-color:#d81b60}.card-maroon:not(.card-outline)>.card-header,.card-maroon:not(.card-outline)>.card-header a{color:#fff}.card-maroon:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-maroon.card-outline{border-top:3px solid #d81b60}.card-maroon.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-maroon.card-outline-tabs>.card-header a.active{border-top:3px solid #d81b60}.bg-gradient-maroon .btn-tool,.bg-maroon .btn-tool,.card-maroon:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-maroon .btn-tool:hover,.bg-maroon .btn-tool:hover,.card-maroon:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-maroon .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-maroon .bootstrap-datetimepicker-widget .table th,.card.bg-maroon .bootstrap-datetimepicker-widget .table td,.card.bg-maroon .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-maroon .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-maroon .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-maroon .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-maroon .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-maroon .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#b41650;color:#fff}.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table td.today:before,.card.bg-maroon .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-maroon .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-maroon .bootstrap-datetimepicker-widget table td.active,.card.bg-maroon .bootstrap-datetimepicker-widget table td.active:hover{background:#e73f7c;color:#fff}.card-blue:not(.card-outline)>.card-header{background-color:#007bff}.card-blue:not(.card-outline)>.card-header,.card-blue:not(.card-outline)>.card-header a{color:#fff}.card-blue:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-blue.card-outline{border-top:3px solid #007bff}.card-blue.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-blue.card-outline-tabs>.card-header a.active{border-top:3px solid #007bff}.bg-blue .btn-tool,.bg-gradient-blue .btn-tool,.card-blue:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-blue .btn-tool:hover,.bg-gradient-blue .btn-tool:hover,.card-blue:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-blue .bootstrap-datetimepicker-widget .table td,.card.bg-blue .bootstrap-datetimepicker-widget .table th,.card.bg-gradient-blue .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-blue .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-blue .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-blue .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-blue .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-blue .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-blue .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#0067d6;color:#fff}.card.bg-blue .bootstrap-datetimepicker-widget table td.today:before,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-blue .bootstrap-datetimepicker-widget table td.active,.card.bg-blue .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-blue .bootstrap-datetimepicker-widget table td.active:hover{background:#3395ff;color:#fff}.card-indigo:not(.card-outline)>.card-header{background-color:#6610f2}.card-indigo:not(.card-outline)>.card-header,.card-indigo:not(.card-outline)>.card-header a{color:#fff}.card-indigo:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-indigo.card-outline{border-top:3px solid #6610f2}.card-indigo.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-indigo.card-outline-tabs>.card-header a.active{border-top:3px solid #6610f2}.bg-gradient-indigo .btn-tool,.bg-indigo .btn-tool,.card-indigo:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-indigo .btn-tool:hover,.bg-indigo .btn-tool:hover,.card-indigo:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-indigo .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-indigo .bootstrap-datetimepicker-widget .table th,.card.bg-indigo .bootstrap-datetimepicker-widget .table td,.card.bg-indigo .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-indigo .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-indigo .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-indigo .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-indigo .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-indigo .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#550bce;color:#fff}.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table td.today:before,.card.bg-indigo .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-indigo .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-indigo .bootstrap-datetimepicker-widget table td.active,.card.bg-indigo .bootstrap-datetimepicker-widget table td.active:hover{background:#8540f5;color:#fff}.card-purple:not(.card-outline)>.card-header{background-color:#6f42c1}.card-purple:not(.card-outline)>.card-header,.card-purple:not(.card-outline)>.card-header a{color:#fff}.card-purple:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-purple.card-outline{border-top:3px solid #6f42c1}.card-purple.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-purple.card-outline-tabs>.card-header a.active{border-top:3px solid #6f42c1}.bg-gradient-purple .btn-tool,.bg-purple .btn-tool,.card-purple:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-purple .btn-tool:hover,.bg-purple .btn-tool:hover,.card-purple:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-purple .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-purple .bootstrap-datetimepicker-widget .table th,.card.bg-purple .bootstrap-datetimepicker-widget .table td,.card.bg-purple .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-purple .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-purple .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-purple .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-purple .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-purple .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-purple .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-purple .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-purple .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-purple .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-purple .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#5d36a4;color:#fff}.card.bg-gradient-purple .bootstrap-datetimepicker-widget table td.today:before,.card.bg-purple .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-purple .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-purple .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-purple .bootstrap-datetimepicker-widget table td.active,.card.bg-purple .bootstrap-datetimepicker-widget table td.active:hover{background:#8c68ce;color:#fff}.card-pink:not(.card-outline)>.card-header{background-color:#e83e8c}.card-pink:not(.card-outline)>.card-header,.card-pink:not(.card-outline)>.card-header a{color:#fff}.card-pink:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-pink.card-outline{border-top:3px solid #e83e8c}.card-pink.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-pink.card-outline-tabs>.card-header a.active{border-top:3px solid #e83e8c}.bg-gradient-pink .btn-tool,.bg-pink .btn-tool,.card-pink:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-pink .btn-tool:hover,.bg-pink .btn-tool:hover,.card-pink:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-pink .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-pink .bootstrap-datetimepicker-widget .table th,.card.bg-pink .bootstrap-datetimepicker-widget .table td,.card.bg-pink .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-pink .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-pink .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-pink .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-pink .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-pink .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-pink .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-pink .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-pink .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-pink .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-pink .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#e21b76;color:#fff}.card.bg-gradient-pink .bootstrap-datetimepicker-widget table td.today:before,.card.bg-pink .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-pink .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-pink .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-pink .bootstrap-datetimepicker-widget table td.active,.card.bg-pink .bootstrap-datetimepicker-widget table td.active:hover{background:#ed6ca7;color:#fff}.card-red:not(.card-outline)>.card-header{background-color:#dc3545}.card-red:not(.card-outline)>.card-header,.card-red:not(.card-outline)>.card-header a{color:#fff}.card-red:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-red.card-outline{border-top:3px solid #dc3545}.card-red.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-red.card-outline-tabs>.card-header a.active{border-top:3px solid #dc3545}.bg-gradient-red .btn-tool,.bg-red .btn-tool,.card-red:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-red .btn-tool:hover,.bg-red .btn-tool:hover,.card-red:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-red .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-red .bootstrap-datetimepicker-widget .table th,.card.bg-red .bootstrap-datetimepicker-widget .table td,.card.bg-red .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-red .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-red .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-red .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-red .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-red .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-red .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-red .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-red .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-red .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-red .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#c62232;color:#fff}.card.bg-gradient-red .bootstrap-datetimepicker-widget table td.today:before,.card.bg-red .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-red .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-red .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-red .bootstrap-datetimepicker-widget table td.active,.card.bg-red .bootstrap-datetimepicker-widget table td.active:hover{background:#e4606d;color:#fff}.card-orange:not(.card-outline)>.card-header{background-color:#fd7e14}.card-orange:not(.card-outline)>.card-header,.card-orange:not(.card-outline)>.card-header a,.card-orange:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-orange.card-outline{border-top:3px solid #fd7e14}.card-orange.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-orange.card-outline-tabs>.card-header a.active{border-top:3px solid #fd7e14}.bg-gradient-orange .btn-tool,.bg-orange .btn-tool,.card-orange:not(.card-outline) .btn-tool{color:rgba(31,45,61,.8)}.bg-gradient-orange .btn-tool:hover,.bg-orange .btn-tool:hover,.card-orange:not(.card-outline) .btn-tool:hover{color:#1f2d3d}.card.bg-gradient-orange .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-orange .bootstrap-datetimepicker-widget .table th,.card.bg-orange .bootstrap-datetimepicker-widget .table td,.card.bg-orange .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-orange .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-orange .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-orange .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-orange .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-orange .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-orange .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-orange .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-orange .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-orange .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-orange .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#e66a02;color:#1f2d3d}.card.bg-gradient-orange .bootstrap-datetimepicker-widget table td.today:before,.card.bg-orange .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#1f2d3d}.card.bg-gradient-orange .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-orange .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-orange .bootstrap-datetimepicker-widget table td.active,.card.bg-orange .bootstrap-datetimepicker-widget table td.active:hover{background:#fd9a47;color:#1f2d3d}.card-yellow:not(.card-outline)>.card-header{background-color:#ffc107}.card-yellow:not(.card-outline)>.card-header,.card-yellow:not(.card-outline)>.card-header a,.card-yellow:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-yellow.card-outline{border-top:3px solid #ffc107}.card-yellow.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-yellow.card-outline-tabs>.card-header a.active{border-top:3px solid #ffc107}.bg-gradient-yellow .btn-tool,.bg-yellow .btn-tool,.card-yellow:not(.card-outline) .btn-tool{color:rgba(31,45,61,.8)}.bg-gradient-yellow .btn-tool:hover,.bg-yellow .btn-tool:hover,.card-yellow:not(.card-outline) .btn-tool:hover{color:#1f2d3d}.card.bg-gradient-yellow .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-yellow .bootstrap-datetimepicker-widget .table th,.card.bg-yellow .bootstrap-datetimepicker-widget .table td,.card.bg-yellow .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-yellow .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-yellow .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-yellow .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-yellow .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-yellow .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#dda600;color:#1f2d3d}.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table td.today:before,.card.bg-yellow .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#1f2d3d}.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-yellow .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-yellow .bootstrap-datetimepicker-widget table td.active,.card.bg-yellow .bootstrap-datetimepicker-widget table td.active:hover{background:#ffce3a;color:#1f2d3d}.card-green:not(.card-outline)>.card-header{background-color:#28a745}.card-green:not(.card-outline)>.card-header,.card-green:not(.card-outline)>.card-header a{color:#fff}.card-green:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-green.card-outline{border-top:3px solid #28a745}.card-green.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-green.card-outline-tabs>.card-header a.active{border-top:3px solid #28a745}.bg-gradient-green .btn-tool,.bg-green .btn-tool,.card-green:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-green .btn-tool:hover,.bg-green .btn-tool:hover,.card-green:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-green .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-green .bootstrap-datetimepicker-widget .table th,.card.bg-green .bootstrap-datetimepicker-widget .table td,.card.bg-green .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-green .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-green .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-green .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-green .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-green .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-green .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-green .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-green .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-green .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-green .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#208637;color:#fff}.card.bg-gradient-green .bootstrap-datetimepicker-widget table td.today:before,.card.bg-green .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-green .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-green .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-green .bootstrap-datetimepicker-widget table td.active,.card.bg-green .bootstrap-datetimepicker-widget table td.active:hover{background:#34ce57;color:#fff}.card-teal:not(.card-outline)>.card-header{background-color:#20c997}.card-teal:not(.card-outline)>.card-header,.card-teal:not(.card-outline)>.card-header a{color:#fff}.card-teal:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-teal.card-outline{border-top:3px solid #20c997}.card-teal.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-teal.card-outline-tabs>.card-header a.active{border-top:3px solid #20c997}.bg-gradient-teal .btn-tool,.bg-teal .btn-tool,.card-teal:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-teal .btn-tool:hover,.bg-teal .btn-tool:hover,.card-teal:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-teal .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-teal .bootstrap-datetimepicker-widget .table th,.card.bg-teal .bootstrap-datetimepicker-widget .table td,.card.bg-teal .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-teal .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-teal .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-teal .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-teal .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-teal .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-teal .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-teal .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-teal .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-teal .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-teal .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#1aa67d;color:#fff}.card.bg-gradient-teal .bootstrap-datetimepicker-widget table td.today:before,.card.bg-teal .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-teal .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-teal .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-teal .bootstrap-datetimepicker-widget table td.active,.card.bg-teal .bootstrap-datetimepicker-widget table td.active:hover{background:#3ce0af;color:#fff}.card-cyan:not(.card-outline)>.card-header{background-color:#17a2b8}.card-cyan:not(.card-outline)>.card-header,.card-cyan:not(.card-outline)>.card-header a{color:#fff}.card-cyan:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-cyan.card-outline{border-top:3px solid #17a2b8}.card-cyan.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-cyan.card-outline-tabs>.card-header a.active{border-top:3px solid #17a2b8}.bg-cyan .btn-tool,.bg-gradient-cyan .btn-tool,.card-cyan:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-cyan .btn-tool:hover,.bg-gradient-cyan .btn-tool:hover,.card-cyan:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-cyan .bootstrap-datetimepicker-widget .table td,.card.bg-cyan .bootstrap-datetimepicker-widget .table th,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-cyan .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-cyan .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-cyan .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-cyan .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-cyan .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#128294;color:#fff}.card.bg-cyan .bootstrap-datetimepicker-widget table td.today:before,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-cyan .bootstrap-datetimepicker-widget table td.active,.card.bg-cyan .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-cyan .bootstrap-datetimepicker-widget table td.active:hover{background:#1fc8e3;color:#fff}.card-white:not(.card-outline)>.card-header{background-color:#fff}.card-white:not(.card-outline)>.card-header,.card-white:not(.card-outline)>.card-header a,.card-white:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-white.card-outline{border-top:3px solid #fff}.card-white.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-white.card-outline-tabs>.card-header a.active{border-top:3px solid #fff}.bg-gradient-white .btn-tool,.bg-white .btn-tool,.card-white:not(.card-outline) .btn-tool{color:rgba(31,45,61,.8)}.bg-gradient-white .btn-tool:hover,.bg-white .btn-tool:hover,.card-white:not(.card-outline) .btn-tool:hover{color:#1f2d3d}.card.bg-gradient-white .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-white .bootstrap-datetimepicker-widget .table th,.card.bg-white .bootstrap-datetimepicker-widget .table td,.card.bg-white .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-white .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-white .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-white .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-white .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-white .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-white .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-white .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-white .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-white .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-white .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#ebebeb;color:#1f2d3d}.card.bg-gradient-white .bootstrap-datetimepicker-widget table td.today:before,.card.bg-white .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#1f2d3d}.card.bg-gradient-white .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-white .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-white .bootstrap-datetimepicker-widget table td.active,.card.bg-white .bootstrap-datetimepicker-widget table td.active:hover{background:#fff;color:#1f2d3d}.card-gray:not(.card-outline)>.card-header{background-color:#6c757d}.card-gray:not(.card-outline)>.card-header,.card-gray:not(.card-outline)>.card-header a{color:#fff}.card-gray:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-gray.card-outline{border-top:3px solid #6c757d}.card-gray.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-gray.card-outline-tabs>.card-header a.active{border-top:3px solid #6c757d}.bg-gradient-gray .btn-tool,.bg-gray .btn-tool,.card-gray:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-gray .btn-tool:hover,.bg-gray .btn-tool:hover,.card-gray:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-gray .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-gray .bootstrap-datetimepicker-widget .table th,.card.bg-gray .bootstrap-datetimepicker-widget .table td,.card.bg-gray .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-gray .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-gray .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-gray .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-gray .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-gray .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-gray .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gray .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gray .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gray .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gray .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#596167;color:#fff}.card.bg-gradient-gray .bootstrap-datetimepicker-widget table td.today:before,.card.bg-gray .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-gray .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-gray .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-gray .bootstrap-datetimepicker-widget table td.active,.card.bg-gray .bootstrap-datetimepicker-widget table td.active:hover{background:#868e96;color:#fff}.card-gray-dark:not(.card-outline)>.card-header{background-color:#343a40}.card-gray-dark:not(.card-outline)>.card-header,.card-gray-dark:not(.card-outline)>.card-header a{color:#fff}.card-gray-dark:not(.card-outline)>.card-header a.active{color:#1f2d3d}.card-gray-dark.card-outline{border-top:3px solid #343a40}.card-gray-dark.card-outline-tabs>.card-header a:hover{border-top:3px solid #dee2e6}.card-gray-dark.card-outline-tabs>.card-header a.active{border-top:3px solid #343a40}.bg-gradient-gray-dark .btn-tool,.bg-gray-dark .btn-tool,.card-gray-dark:not(.card-outline) .btn-tool{color:hsla(0,0%,100%,.8)}.bg-gradient-gray-dark .btn-tool:hover,.bg-gray-dark .btn-tool:hover,.card-gray-dark:not(.card-outline) .btn-tool:hover{color:#fff}.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget .table td,.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget .table th,.card.bg-gray-dark .bootstrap-datetimepicker-widget .table td,.card.bg-gray-dark .bootstrap-datetimepicker-widget .table th{border:none}.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table thead tr:first-child th:hover,.card.bg-gray-dark .bootstrap-datetimepicker-widget table td.day:hover,.card.bg-gray-dark .bootstrap-datetimepicker-widget table td.hour:hover,.card.bg-gray-dark .bootstrap-datetimepicker-widget table td.minute:hover,.card.bg-gray-dark .bootstrap-datetimepicker-widget table td.second:hover,.card.bg-gray-dark .bootstrap-datetimepicker-widget table thead tr:first-child th:hover{background:#222629;color:#fff}.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table td.today:before,.card.bg-gray-dark .bootstrap-datetimepicker-widget table td.today:before{border-bottom-color:#fff}.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table td.active,.card.bg-gradient-gray-dark .bootstrap-datetimepicker-widget table td.active:hover,.card.bg-gray-dark .bootstrap-datetimepicker-widget table td.active,.card.bg-gray-dark .bootstrap-datetimepicker-widget table td.active:hover{background:#4b545c;color:#fff}.card{box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);margin-bottom:1rem}.card.bg-dark .card-header{border-color:#383f45}.card.bg-dark,.card.bg-dark .card-body{color:#fff}.card.maximized-card{height:100%!important;left:0;max-height:100%!important;max-width:100%!important;position:fixed;top:0;width:100%!important;z-index:9999}.card.maximized-card.was-collapsed .card-body{display:block!important}.card.maximized-card [data-widget=collapse]{display:none}.card.maximized-card .card-footer,.card.maximized-card .card-header{border-radius:0!important}.card.collapsed-card .card-body,.card.collapsed-card .card-footer{display:none}.card .nav.flex-column>li{border-bottom:1px solid rgba(0,0,0,.125);margin:0}.card .nav.flex-column>li:last-of-type{border-bottom:0}.card.height-control .card-body{max-height:300px;overflow:auto}.card .border-right{border-right:1px solid rgba(0,0,0,.125)}.card .border-left{border-left:1px solid rgba(0,0,0,.125)}.card.card-tabs:not(.card-outline)>.card-header{border-bottom:0}.card.card-tabs:not(.card-outline)>.card-header .nav-item:first-child .nav-link{margin-left:-1px}.card.card-tabs.card-outline .nav-item{border-bottom:0}.card.card-tabs.card-outline .nav-item:first-child .nav-link{border-left:0;margin-left:0}.card.card-tabs .card-tools{margin:.3rem .5rem}.card.card-tabs:not(.expanding-card).collapsed-card .card-header,.card.card-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs{border-bottom:0}.card.card-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs .nav-item{margin-bottom:0}.card.card-tabs.expanding-card .card-header .nav-tabs .nav-item{margin-bottom:-1px}.card.card-outline-tabs{border-top:0}.card.card-outline-tabs .card-header .nav-item:first-child .nav-link{border-left:0;margin-left:0}.card.card-outline-tabs .card-header a{border-top:3px solid transparent}.card.card-outline-tabs .card-header a:hover{border-top:3px solid #dee2e6}.card.card-outline-tabs .card-header a.active:hover{margin-top:0}.card.card-outline-tabs .card-tools{margin:.5rem .5rem .3rem}.card.card-outline-tabs:not(.expanding-card).collapsed-card .card-header,.card.card-outline-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs{border-bottom:0}.card.card-outline-tabs:not(.expanding-card).collapsed-card .card-header .nav-tabs .nav-item{margin-bottom:0}.card.card-outline-tabs.expanding-card .card-header .nav-tabs .nav-item{margin-bottom:-1px}html.maximized-card{overflow:hidden}.card-body:after,.card-footer:after,.card-header:after{display:block;clear:both;content:""}.card-header{background-color:transparent;border-bottom:1px solid rgba(0,0,0,.125);padding:.75rem 1.25rem;position:relative;border-top-left-radius:.25rem;border-top-right-radius:.25rem}.collapsed-card .card-header{border-bottom:0}.card-header>.card-tools{float:right;margin-right:-.625rem}.card-header>.card-tools .input-group,.card-header>.card-tools .nav,.card-header>.card-tools .pagination{margin-bottom:-.3rem;margin-top:-.3rem}.card-header>.card-tools [data-toggle=tooltip]{position:relative}.card-title{float:left;font-size:1.1rem;font-weight:400;margin:0}.card-text{clear:both}.btn-tool{background:transparent;color:#adb5bd;font-size:.875rem;margin:-.75rem 0;padding:.25rem .5rem}.btn-group.show .btn-tool,.btn-tool:hover{color:#495057}.btn-tool:focus,.show .btn-tool{box-shadow:none!important}.text-sm .card-title{font-size:1rem}.text-sm .nav-link{padding:.4rem .8rem}.card-body>.table{margin-bottom:0}.card-body>.table>thead>tr>td,.card-body>.table>thead>tr>th{border-top-width:0}.card-body .fc{margin-top:5px}.card-body .full-width-chart{margin:-19px}.card-body.p-0 .full-width-chart{margin:-9px}.chart-legend{padding-left:0;list-style:none;margin:10px 0}@media (max-width:576px){.chart-legend>li{float:left;margin-right:10px}}.card-comments{background:#f8f9fa}.card-comments .card-comment{border-bottom:1px solid #e9ecef;padding:8px 0}.card-comments .card-comment:after{display:block;clear:both;content:""}.card-comments .card-comment:last-of-type{border-bottom:0}.card-comments .card-comment:first-of-type{padding-top:0}.card-comments .card-comment img{height:1.875rem;width:1.875rem;float:left}.card-comments .comment-text{color:#78838e;margin-left:40px}.card-comments .username{color:#495057;display:block;font-weight:600}.card-comments .text-muted{font-size:12px;font-weight:400}.todo-list{list-style:none;margin:0;overflow:auto;padding:0}.todo-list>li{border-radius:2px;background:#f8f9fa;border-left:2px solid #e9ecef;color:#495057;margin-bottom:2px;padding:10px}.todo-list>li:last-of-type{margin-bottom:0}.todo-list>li>input[type=checkbox]{margin:0 10px 0 5px}.todo-list>li .text{display:inline-block;font-weight:600;margin-left:5px}.todo-list>li .badge{font-size:.7rem;margin-left:10px}.todo-list>li .tools{color:#dc3545;display:none;float:right}.todo-list>li .tools>.fa,.todo-list>li .tools>.fab,.todo-list>li .tools>.far,.todo-list>li .tools>.fas,.todo-list>li .tools>.glyphicon,.todo-list>li .tools>.ion{cursor:pointer;margin-right:5px}.todo-list>li:hover .tools{display:inline-block}.todo-list>li.done{color:#697582}.todo-list>li.done .text{font-weight:500;text-decoration:line-through}.todo-list>li.done .badge{background:#adb5bd!important}.todo-list .primary{border-left-color:#007bff}.todo-list .secondary{border-left-color:#6c757d}.todo-list .success{border-left-color:#28a745}.todo-list .info{border-left-color:#17a2b8}.todo-list .warning{border-left-color:#ffc107}.todo-list .danger{border-left-color:#dc3545}.todo-list .light{border-left-color:#f8f9fa}.todo-list .dark{border-left-color:#343a40}.todo-list .lightblue{border-left-color:#3c8dbc}.todo-list .navy{border-left-color:#001f3f}.todo-list .olive{border-left-color:#3d9970}.todo-list .lime{border-left-color:#01ff70}.todo-list .fuchsia{border-left-color:#f012be}.todo-list .maroon{border-left-color:#d81b60}.todo-list .blue{border-left-color:#007bff}.todo-list .indigo{border-left-color:#6610f2}.todo-list .purple{border-left-color:#6f42c1}.todo-list .pink{border-left-color:#e83e8c}.todo-list .red{border-left-color:#dc3545}.todo-list .orange{border-left-color:#fd7e14}.todo-list .yellow{border-left-color:#ffc107}.todo-list .green{border-left-color:#28a745}.todo-list .teal{border-left-color:#20c997}.todo-list .cyan{border-left-color:#17a2b8}.todo-list .white{border-left-color:#fff}.todo-list .gray{border-left-color:#6c757d}.todo-list .gray-dark{border-left-color:#343a40}.todo-list .handle{cursor:move;display:inline-block;margin:0 5px}.card-input{max-width:200px}.card-default .nav-item:first-child .nav-link{border-left:0}.modal-dialog .overlay{background-color:#000;display:block;height:100%;left:0;opacity:.7;position:absolute;top:0;width:100%;z-index:1052}.modal-content.bg-warning .modal-footer,.modal-content.bg-warning .modal-header{border-color:#343a40}.modal-content.bg-danger .close,.modal-content.bg-danger .mailbox-attachment-close,.modal-content.bg-info .close,.modal-content.bg-info .mailbox-attachment-close,.modal-content.bg-primary .close,.modal-content.bg-primary .mailbox-attachment-close,.modal-content.bg-secondary .close,.modal-content.bg-secondary .mailbox-attachment-close,.modal-content.bg-success .close,.modal-content.bg-success .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toasts-top-right{position:absolute;right:0;top:0;z-index:1040}.toasts-top-right.fixed{position:fixed}.toasts-top-left{left:0;position:absolute;top:0;z-index:1040}.toasts-top-left.fixed{position:fixed}.toasts-bottom-right{bottom:0;position:absolute;right:0;z-index:1040}.toasts-bottom-right.fixed{position:fixed}.toasts-bottom-left{bottom:0;left:0;position:absolute;z-index:1040}.toasts-bottom-left.fixed{position:fixed}.toast.bg-primary{background:rgba(0,123,255,.9)!important}.toast.bg-primary .close,.toast.bg-primary .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-primary .toast-header{background:rgba(0,123,255,.85);color:#fff}.toast.bg-secondary{background:rgba(108,117,125,.9)!important}.toast.bg-secondary .close,.toast.bg-secondary .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-secondary .toast-header{background:rgba(108,117,125,.85);color:#fff}.toast.bg-success{background:rgba(40,167,69,.9)!important}.toast.bg-success .close,.toast.bg-success .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-success .toast-header{background:rgba(40,167,69,.85);color:#fff}.toast.bg-info{background:rgba(23,162,184,.9)!important}.toast.bg-info .close,.toast.bg-info .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-info .toast-header{background:rgba(23,162,184,.85);color:#fff}.toast.bg-warning{background:rgba(255,193,7,.9)!important}.toast.bg-warning .toast-header{background:rgba(255,193,7,.85);color:#1f2d3d}.toast.bg-danger{background:rgba(220,53,69,.9)!important}.toast.bg-danger .close,.toast.bg-danger .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-danger .toast-header{background:rgba(220,53,69,.85);color:#fff}.toast.bg-light{background:rgba(248,249,250,.9)!important}.toast.bg-light .toast-header{background:rgba(248,249,250,.85);color:#1f2d3d}.toast.bg-dark{background:rgba(52,58,64,.9)!important}.toast.bg-dark .close,.toast.bg-dark .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-dark .toast-header{background:rgba(52,58,64,.85);color:#fff}.toast.bg-lightblue{background:rgba(60,141,188,.9)!important}.toast.bg-lightblue .close,.toast.bg-lightblue .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-lightblue .toast-header{background:rgba(60,141,188,.85);color:#fff}.toast.bg-navy{background:rgba(0,31,63,.9)!important}.toast.bg-navy .close,.toast.bg-navy .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-navy .toast-header{background:rgba(0,31,63,.85);color:#fff}.toast.bg-olive{background:rgba(61,153,112,.9)!important}.toast.bg-olive .close,.toast.bg-olive .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-olive .toast-header{background:rgba(61,153,112,.85);color:#fff}.toast.bg-lime{background:rgba(1,255,112,.9)!important}.toast.bg-lime .toast-header{background:rgba(1,255,112,.85);color:#1f2d3d}.toast.bg-fuchsia{background:rgba(240,18,190,.9)!important}.toast.bg-fuchsia .close,.toast.bg-fuchsia .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-fuchsia .toast-header{background:rgba(240,18,190,.85);color:#fff}.toast.bg-maroon{background:rgba(216,27,96,.9)!important}.toast.bg-maroon .close,.toast.bg-maroon .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-maroon .toast-header{background:rgba(216,27,96,.85);color:#fff}.toast.bg-blue{background:rgba(0,123,255,.9)!important}.toast.bg-blue .close,.toast.bg-blue .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-blue .toast-header{background:rgba(0,123,255,.85);color:#fff}.toast.bg-indigo{background:rgba(102,16,242,.9)!important}.toast.bg-indigo .close,.toast.bg-indigo .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-indigo .toast-header{background:rgba(102,16,242,.85);color:#fff}.toast.bg-purple{background:rgba(111,66,193,.9)!important}.toast.bg-purple .close,.toast.bg-purple .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-purple .toast-header{background:rgba(111,66,193,.85);color:#fff}.toast.bg-pink{background:rgba(232,62,140,.9)!important}.toast.bg-pink .close,.toast.bg-pink .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-pink .toast-header{background:rgba(232,62,140,.85);color:#fff}.toast.bg-red{background:rgba(220,53,69,.9)!important}.toast.bg-red .close,.toast.bg-red .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-red .toast-header{background:rgba(220,53,69,.85);color:#fff}.toast.bg-orange{background:rgba(253,126,20,.9)!important}.toast.bg-orange .toast-header{background:rgba(253,126,20,.85);color:#1f2d3d}.toast.bg-yellow{background:rgba(255,193,7,.9)!important}.toast.bg-yellow .toast-header{background:rgba(255,193,7,.85);color:#1f2d3d}.toast.bg-green{background:rgba(40,167,69,.9)!important}.toast.bg-green .close,.toast.bg-green .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-green .toast-header{background:rgba(40,167,69,.85);color:#fff}.toast.bg-teal{background:rgba(32,201,151,.9)!important}.toast.bg-teal .close,.toast.bg-teal .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-teal .toast-header{background:rgba(32,201,151,.85);color:#fff}.toast.bg-cyan{background:rgba(23,162,184,.9)!important}.toast.bg-cyan .close,.toast.bg-cyan .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-cyan .toast-header{background:rgba(23,162,184,.85);color:#fff}.toast.bg-white{background:hsla(0,0%,100%,.9)!important}.toast.bg-white .toast-header{background:hsla(0,0%,100%,.85);color:#1f2d3d}.toast.bg-gray{background:rgba(108,117,125,.9)!important}.toast.bg-gray .close,.toast.bg-gray .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-gray .toast-header{background:rgba(108,117,125,.85);color:#fff}.toast.bg-gray-dark{background:rgba(52,58,64,.9)!important}.toast.bg-gray-dark .close,.toast.bg-gray-dark .mailbox-attachment-close{color:#fff;text-shadow:0 1px 0 #000}.toast.bg-gray-dark .toast-header{background:rgba(52,58,64,.85);color:#fff}.btn.disabled,.btn:disabled{cursor:not-allowed}.btn.btn-flat{border-radius:0;border-width:1px;box-shadow:none}.btn.btn-file{overflow:hidden;position:relative}.btn.btn-file>input[type=file]{background:#fff;cursor:inherit;display:block;font-size:100px;min-height:100%;min-width:100%;opacity:0;outline:none;position:absolute;right:0;text-align:right;top:0}.text-sm .btn{font-size:.875rem!important}.btn-default{background-color:#f8f9fa;border-color:#ddd;color:#444}.btn-default.hover,.btn-default:active,.btn-default:hover{background-color:#e9ecef;color:#2b2b2b}.btn-app{border-radius:3px;background-color:#f8f9fa;border:1px solid #ddd;color:#6c757d;font-size:12px;height:60px;margin:0 0 10px 10px;min-width:80px;padding:15px 5px;position:relative;text-align:center}.btn-app>.fa,.btn-app>.fab,.btn-app>.far,.btn-app>.fas,.btn-app>.glyphicon,.btn-app>.ion{display:block;font-size:20px}.btn-app:hover{background:#f8f9fa;border-color:#aaa;color:#444}.btn-app:active,.btn-app:focus{box-shadow:inset 0 3px 5px rgba(0,0,0,.125)}.btn-app>.badge{font-size:10px;font-weight:400;position:absolute;right:-10px;top:-3px}.btn-xs{padding:.125rem .25rem;font-size:.75rem;line-height:1.5;border-radius:.15rem}.callout{border-radius:.25rem;box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);background-color:#fff;border-left:5px solid #e9ecef;margin-bottom:1rem;padding:1rem}.callout a{color:#495057;text-decoration:underline}.callout a:hover{color:#e9ecef}.callout p:last-child{margin-bottom:0}.callout.callout-danger{border-left-color:#bd2130}.callout.callout-warning{border-left-color:#d39e00}.callout.callout-info{border-left-color:#117a8b}.callout.callout-success{border-left-color:#1e7e34}.alert .icon{margin-right:10px}.alert .close,.alert .mailbox-attachment-close{color:#000;opacity:.2}.alert .close:hover,.alert .mailbox-attachment-close:hover{opacity:.5}.alert a{color:#fff;text-decoration:underline}.alert-primary{color:#fff;background:#007bff;border-color:#006fe6}.alert-default-primary{color:#004085;background-color:#cce5ff;border-color:#b8daff}.alert-default-primary hr{border-top-color:#9fcdff}.alert-default-primary .alert-link{color:#002752}.alert-secondary{color:#fff;background:#6c757d;border-color:#60686f}.alert-default-secondary{color:#383d41;background-color:#e2e3e5;border-color:#d6d8db}.alert-default-secondary hr{border-top-color:#c8cbcf}.alert-default-secondary .alert-link{color:#202326}.alert-success{color:#fff;background:#28a745;border-color:#23923d}.alert-default-success{color:#155724;background-color:#d4edda;border-color:#c3e6cb}.alert-default-success hr{border-top-color:#b1dfbb}.alert-default-success .alert-link{color:#0b2e13}.alert-info{color:#fff;background:#17a2b8;border-color:#148ea1}.alert-default-info{color:#0c5460;background-color:#d1ecf1;border-color:#bee5eb}.alert-default-info hr{border-top-color:#abdde5}.alert-default-info .alert-link{color:#062c33}.alert-warning{color:#1f2d3d;background:#ffc107;border-color:#edb100}.alert-default-warning{color:#856404;background-color:#fff3cd;border-color:#ffeeba}.alert-default-warning hr{border-top-color:#ffe8a1}.alert-default-warning .alert-link{color:#533f03}.alert-danger{color:#fff;background:#dc3545;border-color:#d32535}.alert-default-danger{color:#721c24;background-color:#f8d7da;border-color:#f5c6cb}.alert-default-danger hr{border-top-color:#f1b0b7}.alert-default-danger .alert-link{color:#491217}.alert-light{color:#1f2d3d;background:#f8f9fa;border-color:#e9ecef}.alert-default-light{color:#818182;background-color:#fefefe;border-color:#fdfdfe}.alert-default-light hr{border-top-color:#ececf6}.alert-default-light .alert-link{color:#686868}.alert-dark{color:#fff;background:#343a40;border-color:#292d32}.alert-default-dark{color:#1b1e21;background-color:#d6d8d9;border-color:#c6c8ca}.alert-default-dark hr{border-top-color:#b9bbbe}.alert-default-dark .alert-link{color:#040505}.table:not(.table-dark){color:inherit}.table.table-head-fixed thead tr:first-child th{background-color:#fff;border-bottom:0;box-shadow:inset 0 1px 0 #dee2e6,inset 0 -1px 0 #dee2e6;position:-webkit-sticky;position:sticky;top:0;z-index:10}.table.table-head-fixed.table-dark thead tr:first-child th{background-color:#212529;box-shadow:inset 0 1px 0 #383f45,inset 0 -1px 0 #383f45}.table.no-border,.table.no-border td,.table.no-border th{border:0}.table.text-center,.table.text-center td,.table.text-center th{text-align:center}.table.table-valign-middle tbody>tr>td,.table.table-valign-middle tbody>tr>th,.table.table-valign-middle thead>tr>td,.table.table-valign-middle thead>tr>th{vertical-align:middle}.card-body.p-0 .table tbody>tr>td:first-of-type,.card-body.p-0 .table tbody>tr>th:first-of-type,.card-body.p-0 .table thead>tr>td:first-of-type,.card-body.p-0 .table thead>tr>th:first-of-type{padding-left:1.5rem}.card-body.p-0 .table tbody>tr>td:last-of-type,.card-body.p-0 .table tbody>tr>th:last-of-type,.card-body.p-0 .table thead>tr>td:last-of-type,.card-body.p-0 .table thead>tr>th:last-of-type{padding-right:1.5rem}.carousel-control.left,.carousel-control.right{background-image:none}.carousel-control>.fa,.carousel-control>.fab,.carousel-control>.far,.carousel-control>.fas,.carousel-control>.glyphicon,.carousel-control>.ion{display:inline-block;font-size:40px;margin-top:-20px;position:absolute;top:50%;z-index:5}.small-box{border-radius:.25rem;box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);display:block;margin-bottom:20px;position:relative}.small-box>.inner{padding:10px}.small-box>.small-box-footer{background:rgba(0,0,0,.1);color:hsla(0,0%,100%,.8);display:block;padding:3px 0;position:relative;text-align:center;text-decoration:none;z-index:10}.small-box>.small-box-footer:hover{background:rgba(0,0,0,.15);color:#fff}.small-box h3{font-size:2.2rem;font-weight:700;margin:0 0 10px;padding:0;white-space:nowrap}@media (min-width:992px){.col-lg-2 .small-box h3,.col-lg-3 .small-box h3,.col-md-2 .small-box h3,.col-md-3 .small-box h3,.col-xl-2 .small-box h3,.col-xl-3 .small-box h3{font-size:1.6rem}}@media (min-width:1200px){.col-lg-2 .small-box h3,.col-lg-3 .small-box h3,.col-md-2 .small-box h3,.col-md-3 .small-box h3,.col-xl-2 .small-box h3,.col-xl-3 .small-box h3{font-size:2.2rem}}.small-box p{font-size:1rem}.small-box p>small{color:#f8f9fa;display:block;font-size:.9rem;margin-top:5px}.small-box h3,.small-box p{z-index:5}.small-box .icon{color:rgba(0,0,0,.15);z-index:0}.small-box .icon>i{font-size:90px;position:absolute;right:15px;top:15px;transition:all .3s linear}.small-box .icon>i.fa,.small-box .icon>i.fab,.small-box .icon>i.far,.small-box .icon>i.fas,.small-box .icon>i.glyphicon,.small-box .icon>i.ion{font-size:70px;top:20px}.small-box:hover{text-decoration:none}.small-box:hover .icon>i{font-size:95px}.small-box:hover .icon>i.fa,.small-box:hover .icon>i.fab,.small-box:hover .icon>i.far,.small-box:hover .icon>i.fas,.small-box:hover .icon>i.glyphicon,.small-box:hover .icon>i.ion{font-size:75px}@media (max-width:767.98px){.small-box{text-align:center}.small-box .icon{display:none}.small-box p{font-size:12px}}.info-box{box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);border-radius:.25rem;background:#fff;display:flex;margin-bottom:1rem;min-height:80px;padding:.5rem;position:relative;width:100%}.info-box .progress{background-color:rgba(0,0,0,.125);height:2px;margin:5px 0}.info-box .progress .progress-bar{background-color:#fff}.info-box .info-box-icon{border-radius:.25rem;align-items:center;display:flex;font-size:1.875rem;justify-content:center;text-align:center;width:70px}.info-box .info-box-icon>img{max-width:100%}.info-box .info-box-content{display:flex;flex-direction:column;justify-content:center;line-height:120%;flex:1;padding:0 10px}.info-box .info-box-number{display:block;margin-top:.25rem;font-weight:700}.info-box .info-box-text,.info-box .progress-description{display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.info-box .info-box .bg-gradient-primary,.info-box .info-box .bg-primary{color:#fff}.info-box .info-box .bg-gradient-primary .progress-bar,.info-box .info-box .bg-primary .progress-bar{background-color:#fff}.info-box .info-box .bg-gradient-secondary,.info-box .info-box .bg-secondary{color:#fff}.info-box .info-box .bg-gradient-secondary .progress-bar,.info-box .info-box .bg-secondary .progress-bar{background-color:#fff}.info-box .info-box .bg-gradient-success,.info-box .info-box .bg-success{color:#fff}.info-box .info-box .bg-gradient-success .progress-bar,.info-box .info-box .bg-success .progress-bar{background-color:#fff}.info-box .info-box .bg-gradient-info,.info-box .info-box .bg-info{color:#fff}.info-box .info-box .bg-gradient-info .progress-bar,.info-box .info-box .bg-info .progress-bar{background-color:#fff}.info-box .info-box .bg-gradient-warning,.info-box .info-box .bg-warning{color:#1f2d3d}.info-box .info-box .bg-gradient-warning .progress-bar,.info-box .info-box .bg-warning .progress-bar{background-color:#1f2d3d}.info-box .info-box .bg-danger,.info-box .info-box .bg-gradient-danger{color:#fff}.info-box .info-box .bg-danger .progress-bar,.info-box .info-box .bg-gradient-danger .progress-bar{background-color:#fff}.info-box .info-box .bg-gradient-light,.info-box .info-box .bg-light{color:#1f2d3d}.info-box .info-box .bg-gradient-light .progress-bar,.info-box .info-box .bg-light .progress-bar{background-color:#1f2d3d}.info-box .info-box .bg-dark,.info-box .info-box .bg-gradient-dark{color:#fff}.info-box .info-box .bg-dark .progress-bar,.info-box .info-box .bg-gradient-dark .progress-bar{background-color:#fff}.info-box .info-box-more{display:block}.info-box .progress-description{margin:0}@media (min-width:768px){.col-lg-2 .info-box .progress-description,.col-lg-3 .info-box .progress-description,.col-md-2 .info-box .progress-description,.col-md-3 .info-box .progress-description,.col-xl-2 .info-box .progress-description,.col-xl-3 .info-box .progress-description{display:none}}@media (min-width:992px){.col-lg-2 .info-box .progress-description,.col-lg-3 .info-box .progress-description,.col-md-2 .info-box .progress-description,.col-md-3 .info-box .progress-description,.col-xl-2 .info-box .progress-description,.col-xl-3 .info-box .progress-description{font-size:.75rem;display:block}}@media (min-width:1200px){.col-lg-2 .info-box .progress-description,.col-lg-3 .info-box .progress-description,.col-md-2 .info-box .progress-description,.col-md-3 .info-box .progress-description,.col-xl-2 .info-box .progress-description,.col-xl-3 .info-box .progress-description{font-size:1rem;display:block}}.timeline{margin:0 0 45px;padding:0;position:relative}.timeline:before{border-radius:.25rem;background:#dee2e6;bottom:0;content:"";left:31px;margin:0;position:absolute;top:0;width:4px}.timeline>div{margin-bottom:15px;margin-right:10px;position:relative}.timeline>div:after,.timeline>div:before{content:"";display:table}.timeline>div>.timeline-item{box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);border-radius:.25rem;background:#fff;color:#495057;margin-left:60px;margin-right:15px;margin-top:0;padding:0;position:relative}.timeline>div>.timeline-item>.time{color:#999;float:right;font-size:12px;padding:10px}.timeline>div>.timeline-item>.timeline-header{border-bottom:1px solid rgba(0,0,0,.125);color:#495057;font-size:16px;line-height:1.1;margin:0;padding:10px}.timeline>div>.timeline-item>.timeline-header>a{font-weight:600}.timeline>div>.timeline-item>.timeline-body,.timeline>div>.timeline-item>.timeline-footer{padding:10px}.timeline>div>.timeline-item>.timeline-body>img{margin:10px}.timeline>div>.timeline-item>.timeline-body>dl,.timeline>div>.timeline-item>.timeline-body ol,.timeline>div>.timeline-item>.timeline-body ul{margin:0}.timeline>div>.timeline-item>.timeline-footer>a{color:#fff}.timeline>div>.fa,.timeline>div>.fab,.timeline>div>.far,.timeline>div>.fas,.timeline>div>.glyphicon,.timeline>div>.ion{background:#adb5bd;border-radius:50%;font-size:15px;height:30px;left:18px;line-height:30px;position:absolute;text-align:center;top:0;width:30px}.timeline>.time-label>span{border-radius:4px;background-color:#fff;display:inline-block;font-weight:600;padding:5px}.timeline-inverse>div>.timeline-item{box-shadow:none;background:#f8f9fa;border:1px solid #dee2e6}.timeline-inverse>div>.timeline-item>.timeline-header{border-bottom-color:#dee2e6}.products-list{list-style:none;margin:0;padding:0}.products-list>.item{border-radius:.25rem;background:#fff;padding:10px 0}.products-list>.item:after{display:block;clear:both;content:""}.products-list .product-img{float:left}.products-list .product-img img{height:50px;width:50px}.products-list .product-info{margin-left:60px}.products-list .product-title{font-weight:600}.products-list .product-description{color:#6c757d;display:block;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.product-list-in-card>.item{border-radius:0;border-bottom:1px solid rgba(0,0,0,.125)}.product-list-in-card>.item:last-of-type{border-bottom-width:0}.direct-chat .card-body{overflow-x:hidden;padding:0;position:relative}.direct-chat.chat-pane-open .direct-chat-contacts{transform:translate(0)}.direct-chat.timestamp-light .direct-chat-timestamp{color:#30465f}.direct-chat.timestamp-dark .direct-chat-timestamp{color:#ccc}.direct-chat-messages{transform:translate(0);height:250px;overflow:auto;padding:10px}.direct-chat-msg,.direct-chat-text{display:block}.direct-chat-msg{margin-bottom:10px}.direct-chat-msg:after{display:block;clear:both;content:""}.direct-chat-contacts,.direct-chat-messages{transition:transform .5s ease-in-out}.direct-chat-text{border-radius:.3rem;background:#d2d6de;border:1px solid #d2d6de;color:#444;margin:5px 0 0 50px;padding:5px 10px;position:relative}.direct-chat-text:after,.direct-chat-text:before{border:solid transparent;border-right:solid #d2d6de;content:" ";height:0;pointer-events:none;position:absolute;right:100%;top:15px;width:0}.direct-chat-text:after{border-width:5px;margin-top:-5px}.direct-chat-text:before{border-width:6px;margin-top:-6px}.right .direct-chat-text{margin-left:0;margin-right:50px}.right .direct-chat-text:after,.right .direct-chat-text:before{border-left-color:#d2d6de;border-right-color:transparent;left:100%;right:auto}.direct-chat-img{border-radius:50%;float:left;height:40px;width:40px}.right .direct-chat-img{float:right}.direct-chat-infos{display:block;font-size:.875rem;margin-bottom:2px}.direct-chat-name{font-weight:600}.direct-chat-timestamp{color:#697582}.direct-chat-contacts-open .direct-chat-contacts{transform:translate(0)}.direct-chat-contacts{transform:translate(101%);background:#343a40;bottom:0;color:#fff;height:250px;overflow:auto;position:absolute;top:0;width:100%}.direct-chat-contacts-light{background:#f8f9fa}.direct-chat-contacts-light .contacts-list-name{color:#495057}.direct-chat-contacts-light .contacts-list-date{color:#6c757d}.direct-chat-contacts-light .contacts-list-msg{color:#545b62}.contacts-list{padding-left:0;list-style:none}.contacts-list>li{border-bottom:1px solid rgba(0,0,0,.2);margin:0;padding:10px}.contacts-list>li:after{display:block;clear:both;content:""}.contacts-list>li:last-of-type{border-bottom:0}.contacts-list-img{border-radius:50%;float:left;width:40px}.contacts-list-info{color:#fff;margin-left:45px}.contacts-list-name,.contacts-list-status{display:block}.contacts-list-name{font-weight:600}.contacts-list-status{font-size:.875rem}.contacts-list-date{color:#ced4da;font-weight:400}.contacts-list-msg{color:#b1bbc4}.direct-chat-primary .right>.direct-chat-text{background:#007bff;border-color:#007bff;color:#fff}.direct-chat-primary .right>.direct-chat-text:after,.direct-chat-primary .right>.direct-chat-text:before{border-left-color:#007bff}.direct-chat-secondary .right>.direct-chat-text{background:#6c757d;border-color:#6c757d;color:#fff}.direct-chat-secondary .right>.direct-chat-text:after,.direct-chat-secondary .right>.direct-chat-text:before{border-left-color:#6c757d}.direct-chat-success .right>.direct-chat-text{background:#28a745;border-color:#28a745;color:#fff}.direct-chat-success .right>.direct-chat-text:after,.direct-chat-success .right>.direct-chat-text:before{border-left-color:#28a745}.direct-chat-info .right>.direct-chat-text{background:#17a2b8;border-color:#17a2b8;color:#fff}.direct-chat-info .right>.direct-chat-text:after,.direct-chat-info .right>.direct-chat-text:before{border-left-color:#17a2b8}.direct-chat-warning .right>.direct-chat-text{background:#ffc107;border-color:#ffc107;color:#1f2d3d}.direct-chat-warning .right>.direct-chat-text:after,.direct-chat-warning .right>.direct-chat-text:before{border-left-color:#ffc107}.direct-chat-danger .right>.direct-chat-text{background:#dc3545;border-color:#dc3545;color:#fff}.direct-chat-danger .right>.direct-chat-text:after,.direct-chat-danger .right>.direct-chat-text:before{border-left-color:#dc3545}.direct-chat-light .right>.direct-chat-text{background:#f8f9fa;border-color:#f8f9fa;color:#1f2d3d}.direct-chat-light .right>.direct-chat-text:after,.direct-chat-light .right>.direct-chat-text:before{border-left-color:#f8f9fa}.direct-chat-dark .right>.direct-chat-text{background:#343a40;border-color:#343a40;color:#fff}.direct-chat-dark .right>.direct-chat-text:after,.direct-chat-dark .right>.direct-chat-text:before{border-left-color:#343a40}.direct-chat-lightblue .right>.direct-chat-text{background:#3c8dbc;border-color:#3c8dbc;color:#fff}.direct-chat-lightblue .right>.direct-chat-text:after,.direct-chat-lightblue .right>.direct-chat-text:before{border-left-color:#3c8dbc}.direct-chat-navy .right>.direct-chat-text{background:#001f3f;border-color:#001f3f;color:#fff}.direct-chat-navy .right>.direct-chat-text:after,.direct-chat-navy .right>.direct-chat-text:before{border-left-color:#001f3f}.direct-chat-olive .right>.direct-chat-text{background:#3d9970;border-color:#3d9970;color:#fff}.direct-chat-olive .right>.direct-chat-text:after,.direct-chat-olive .right>.direct-chat-text:before{border-left-color:#3d9970}.direct-chat-lime .right>.direct-chat-text{background:#01ff70;border-color:#01ff70;color:#1f2d3d}.direct-chat-lime .right>.direct-chat-text:after,.direct-chat-lime .right>.direct-chat-text:before{border-left-color:#01ff70}.direct-chat-fuchsia .right>.direct-chat-text{background:#f012be;border-color:#f012be;color:#fff}.direct-chat-fuchsia .right>.direct-chat-text:after,.direct-chat-fuchsia .right>.direct-chat-text:before{border-left-color:#f012be}.direct-chat-maroon .right>.direct-chat-text{background:#d81b60;border-color:#d81b60;color:#fff}.direct-chat-maroon .right>.direct-chat-text:after,.direct-chat-maroon .right>.direct-chat-text:before{border-left-color:#d81b60}.direct-chat-blue .right>.direct-chat-text{background:#007bff;border-color:#007bff;color:#fff}.direct-chat-blue .right>.direct-chat-text:after,.direct-chat-blue .right>.direct-chat-text:before{border-left-color:#007bff}.direct-chat-indigo .right>.direct-chat-text{background:#6610f2;border-color:#6610f2;color:#fff}.direct-chat-indigo .right>.direct-chat-text:after,.direct-chat-indigo .right>.direct-chat-text:before{border-left-color:#6610f2}.direct-chat-purple .right>.direct-chat-text{background:#6f42c1;border-color:#6f42c1;color:#fff}.direct-chat-purple .right>.direct-chat-text:after,.direct-chat-purple .right>.direct-chat-text:before{border-left-color:#6f42c1}.direct-chat-pink .right>.direct-chat-text{background:#e83e8c;border-color:#e83e8c;color:#fff}.direct-chat-pink .right>.direct-chat-text:after,.direct-chat-pink .right>.direct-chat-text:before{border-left-color:#e83e8c}.direct-chat-red .right>.direct-chat-text{background:#dc3545;border-color:#dc3545;color:#fff}.direct-chat-red .right>.direct-chat-text:after,.direct-chat-red .right>.direct-chat-text:before{border-left-color:#dc3545}.direct-chat-orange .right>.direct-chat-text{background:#fd7e14;border-color:#fd7e14;color:#1f2d3d}.direct-chat-orange .right>.direct-chat-text:after,.direct-chat-orange .right>.direct-chat-text:before{border-left-color:#fd7e14}.direct-chat-yellow .right>.direct-chat-text{background:#ffc107;border-color:#ffc107;color:#1f2d3d}.direct-chat-yellow .right>.direct-chat-text:after,.direct-chat-yellow .right>.direct-chat-text:before{border-left-color:#ffc107}.direct-chat-green .right>.direct-chat-text{background:#28a745;border-color:#28a745;color:#fff}.direct-chat-green .right>.direct-chat-text:after,.direct-chat-green .right>.direct-chat-text:before{border-left-color:#28a745}.direct-chat-teal .right>.direct-chat-text{background:#20c997;border-color:#20c997;color:#fff}.direct-chat-teal .right>.direct-chat-text:after,.direct-chat-teal .right>.direct-chat-text:before{border-left-color:#20c997}.direct-chat-cyan .right>.direct-chat-text{background:#17a2b8;border-color:#17a2b8;color:#fff}.direct-chat-cyan .right>.direct-chat-text:after,.direct-chat-cyan .right>.direct-chat-text:before{border-left-color:#17a2b8}.direct-chat-white .right>.direct-chat-text{background:#fff;border-color:#fff;color:#1f2d3d}.direct-chat-white .right>.direct-chat-text:after,.direct-chat-white .right>.direct-chat-text:before{border-left-color:#fff}.direct-chat-gray .right>.direct-chat-text{background:#6c757d;border-color:#6c757d;color:#fff}.direct-chat-gray .right>.direct-chat-text:after,.direct-chat-gray .right>.direct-chat-text:before{border-left-color:#6c757d}.direct-chat-gray-dark .right>.direct-chat-text{background:#343a40;border-color:#343a40;color:#fff}.direct-chat-gray-dark .right>.direct-chat-text:after,.direct-chat-gray-dark .right>.direct-chat-text:before{border-left-color:#343a40}.users-list{padding-left:0;list-style:none}.users-list>li{float:left;padding:10px;text-align:center;width:25%}.users-list>li img{border-radius:50%;height:auto;max-width:100%}.users-list>li>a:hover,.users-list>li>a:hover .users-list-name{color:#999}.users-list-date,.users-list-name{display:block}.users-list-name{color:#495057;font-size:.875rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.users-list-date{color:#748290;font-size:12px}.card-widget{border:0;position:relative}.widget-user .widget-user-header{border-top-left-radius:.25rem;border-top-right-radius:.25rem;height:135px;padding:1rem;text-align:center}.widget-user .widget-user-username{font-size:25px;font-weight:300;margin-bottom:0;margin-top:0;text-shadow:0 1px 1px rgba(0,0,0,.2)}.widget-user .widget-user-desc{margin-top:0}.widget-user .widget-user-image{left:50%;margin-left:-45px;position:absolute;top:80px}.widget-user .widget-user-image>img{border:3px solid #fff;height:auto;width:90px}.widget-user .card-footer{padding-top:50px}.widget-user-2 .widget-user-header{border-top-left-radius:.25rem;border-top-right-radius:.25rem;padding:1rem}.widget-user-2 .widget-user-username{font-size:25px;font-weight:300;margin-bottom:5px;margin-top:5px}.widget-user-2 .widget-user-desc{margin-top:0}.widget-user-2 .widget-user-desc,.widget-user-2 .widget-user-username{margin-left:75px}.widget-user-2 .widget-user-image>img{float:left;height:auto;width:65px}.mailbox-messages>.table{margin:0}.mailbox-controls{padding:5px}.mailbox-controls.with-border,.mailbox-read-info{border-bottom:1px solid rgba(0,0,0,.125)}.mailbox-read-info{padding:10px}.mailbox-read-info h3{font-size:20px;margin:0}.mailbox-read-info h5{margin:0;padding:5px 0 0}.mailbox-read-time{color:#999;font-size:13px}.mailbox-read-message{padding:10px}.mailbox-attachments{padding-left:0;list-style:none}.mailbox-attachments li{border:1px solid #eee;float:left;margin-bottom:10px;margin-right:10px;width:200px}.mailbox-attachment-name{color:#666;font-weight:700}.mailbox-attachment-icon,.mailbox-attachment-info,.mailbox-attachment-size{display:block}.mailbox-attachment-info{background:#f8f9fa;padding:10px}.mailbox-attachment-size{color:#999;font-size:12px}.mailbox-attachment-size>span{display:inline-block;padding-top:.75rem}.mailbox-attachment-icon{color:#666;font-size:65px;max-height:132.5px;padding:20px 10px;text-align:center}.mailbox-attachment-icon.has-img{padding:0}.mailbox-attachment-icon.has-img>img{height:auto;max-width:100%}.lockscreen{background:#e9ecef}.lockscreen .lockscreen-name{font-weight:600;text-align:center}.lockscreen-logo{font-size:35px;font-weight:300;margin-bottom:25px;text-align:center}.lockscreen-logo a{color:#495057}.lockscreen-wrapper{margin:10% auto 0;max-width:400px}.lockscreen-item{border-radius:4px;background:#fff;margin:10px auto 30px;padding:0;position:relative;width:290px}.lockscreen-image{border-radius:50%;background:#fff;left:-10px;padding:5px;position:absolute;top:-25px;z-index:10}.lockscreen-image>img{border-radius:50%;height:70px;width:70px}.lockscreen-credentials{margin-left:70px}.lockscreen-credentials .form-control{border:0}.lockscreen-credentials .btn{background-color:#fff;border:0;padding:0 10px}.lockscreen-footer{margin-top:10px}.login-logo,.register-logo{font-size:2.1rem;font-weight:300;margin-bottom:.9rem;text-align:center}.login-logo a,.register-logo a{color:#495057}.login-page,.register-page{align-items:center;background:#e9ecef;display:flex;flex-direction:column;height:100vh;justify-content:center}.login-box,.register-box{width:360px}@media (max-width:576px){.login-box,.register-box{margin-top:.5rem;width:90%}}.login-card-body,.register-card-body{background:#fff;border-top:0;color:#666;padding:20px}.login-card-body .input-group .form-control,.register-card-body .input-group .form-control{border-right:0}.login-card-body .input-group .form-control:focus,.register-card-body .input-group .form-control:focus{box-shadow:none}.login-card-body .input-group .form-control:focus~.input-group-append .input-group-text,.register-card-body .input-group .form-control:focus~.input-group-append .input-group-text{border-color:#80bdff}.login-card-body .input-group .form-control.is-valid:focus,.register-card-body .input-group .form-control.is-valid:focus{box-shadow:none}.login-card-body .input-group .form-control.is-valid~.input-group-append .input-group-text,.register-card-body .input-group .form-control.is-valid~.input-group-append .input-group-text{border-color:#28a745}.login-card-body .input-group .form-control.is-invalid:focus,.register-card-body .input-group .form-control.is-invalid:focus{box-shadow:none}.login-card-body .input-group .form-control.is-invalid~.input-group-append .input-group-text,.register-card-body .input-group .form-control.is-invalid~.input-group-append .input-group-text{border-color:#dc3545}.login-card-body .input-group .input-group-text,.register-card-body .input-group .input-group-text{background-color:transparent;border-bottom-right-radius:.25rem;border-left:0;border-top-right-radius:.25rem;color:#777;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out}.login-box-msg,.register-box-msg{margin:0;padding:0 20px 20px;text-align:center}.social-auth-links{margin:10px 0}.error-page{margin:20px auto 0;width:600px}@media (max-width:767.98px){.error-page{width:100%}}.error-page>.headline{float:left;font-size:100px;font-weight:300}@media (max-width:767.98px){.error-page>.headline{float:none;text-align:center}}.error-page>.error-content{display:block;margin-left:190px}@media (max-width:767.98px){.error-page>.error-content{margin-left:0}}.error-page>.error-content>h3{font-size:25px;font-weight:300}@media (max-width:767.98px){.error-page>.error-content>h3{text-align:center}}.invoice{background:#fff;border:1px solid rgba(0,0,0,.125);position:relative}.invoice-title{margin-top:0}.profile-user-img{border:3px solid #adb5bd;margin:0 auto;padding:3px;width:100px}.profile-username{font-size:21px;margin-top:5px}.post{border-bottom:1px solid #adb5bd;color:#666;margin-bottom:15px;padding-bottom:15px}.post:last-of-type{border-bottom:0;margin-bottom:0;padding-bottom:0}.post .user-block{margin-bottom:15px;width:100%}.post .row{width:100%}.product-image{max-width:100%;height:auto;width:100%}.product-image-thumbs{align-items:stretch;display:flex;margin-top:2rem}.product-image-thumb{box-shadow:0 1px 2px rgba(0,0,0,.075);border-radius:.25rem;background-color:#fff;border:1px solid #dee2e6;display:flex;margin-right:1rem;max-width:7rem;padding:.5rem}.product-image-thumb img{max-width:100%;height:auto;align-self:center}.product-image-thumb:hover{opacity:.5}.product-share a{margin-right:.5rem}.projects td{vertical-align:middle}.projects .list-inline{margin-bottom:0}.projects .table-avatar img,.projects img.table-avatar{border-radius:50%;display:inline;width:2.5rem}.projects .project-state{text-align:center}.fc-button{background:#f8f9fa;background-image:none;border-color:#ddd;color:#495057}.fc-button.hover,.fc-button:active,.fc-button:hover{background-color:#e9e9e9}.fc-header-title h2{color:#666;font-size:15px;line-height:1.6em;margin-left:10px}.fc-header-right{padding-right:10px}.fc-header-left{padding-left:10px}.fc-widget-header{background:#fafafa}.fc-grid{border:0;width:100%}.fc-widget-content:first-of-type,.fc-widget-header:first-of-type{border-left:0;border-right:0}.fc-widget-content:last-of-type,.fc-widget-header:last-of-type{border-right:0}.fc-toolbar,.fc-toolbar.fc-header-toolbar{margin:0;padding:1rem}@media (max-width:575.98px){.fc-toolbar{flex-direction:column}.fc-toolbar .fc-left{order:1;margin-bottom:.5rem}.fc-toolbar .fc-center{order:0;margin-bottom:.375rem}.fc-toolbar .fc-right{order:2}}.fc-day-number{font-size:20px;font-weight:300;padding-right:10px}.fc-color-picker{list-style:none;margin:0;padding:0}.fc-color-picker>li{float:left;font-size:30px;line-height:30px;margin-right:5px}.fc-color-picker>li .fa,.fc-color-picker>li .fab,.fc-color-picker>li .far,.fc-color-picker>li .fas,.fc-color-picker>li .glyphicon,.fc-color-picker>li .ion{transition:transform .3s linear}.fc-color-picker>li .fa:hover,.fc-color-picker>li .fab:hover,.fc-color-picker>li .far:hover,.fc-color-picker>li .fas:hover,.fc-color-picker>li .glyphicon:hover,.fc-color-picker>li .ion:hover{transform:rotate(30deg)}#add-new-event{transition:all .3s linear}.external-event{box-shadow:0 0 1px rgba(0,0,0,.125),0 1px 3px rgba(0,0,0,.2);border-radius:.25rem;cursor:move;font-weight:700;margin-bottom:4px;padding:5px 10px}.external-event:hover{box-shadow:inset 0 0 90px rgba(0,0,0,.2)}.select2-container--default .select2-selection--single{border:1px solid #ced4da;padding:.46875rem .75rem;height:calc(2.25rem + 2px)}.select2-container--default.select2-container--open .select2-selection--single{border-color:#80bdff}.select2-container--default .select2-dropdown{border:1px solid #ced4da}.select2-container--default .select2-results__option{padding:6px 12px;-moz-user-select:none;-ms-user-select:none;user-select:none;-webkit-user-select:none}.select2-container--default .select2-selection--single .select2-selection__rendered{padding-left:0;height:auto;margin-top:-3px}.select2-container--default[dir=rtl] .select2-selection--single .select2-selection__rendered{padding-right:6px;padding-left:20px}.select2-container--default .select2-selection--single .select2-selection__arrow{height:31px;right:6px}.select2-container--default .select2-selection--single .select2-selection__arrow b{margin-top:0}.select2-container--default .select2-dropdown .select2-search__field,.select2-container--default .select2-search--inline .select2-search__field{border:1px solid #ced4da}.select2-container--default .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-search--inline .select2-search__field:focus{outline:none;border:1px solid #80bdff}.select2-container--default .select2-dropdown.select2-dropdown--below{border-top:0}.select2-container--default .select2-dropdown.select2-dropdown--above{border-bottom:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#6c757d}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#dee2e6}.select2-container--default .select2-results__option[aria-selected=true],.select2-container--default .select2-results__option[aria-selected=true]:hover{color:#1f2d3d}.select2-container--default .select2-results__option--highlighted{background-color:#007bff;color:#fff}.select2-container--default .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#0074f0;color:#fff}.select2-container--default .select2-selection--multiple{border:1px solid #ced4da;min-height:calc(2.25rem + 2px)}.select2-container--default .select2-selection--multiple:focus{border-color:#80bdff}.select2-container--default .select2-selection--multiple .select2-selection__rendered{padding:0 .375rem .375rem;margin-bottom:-.375rem}.select2-container--default .select2-selection--multiple .select2-selection__rendered li:first-child.select2-search.select2-search--inline{width:100%;margin-left:.375rem}.select2-container--default .select2-selection--multiple .select2-selection__rendered li:first-child.select2-search.select2-search--inline .select2-search__field{width:100%!important}.select2-container--default .select2-selection--multiple .select2-selection__rendered .select2-search.select2-search--inline .select2-search__field{border:0;margin-top:6px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#007bff;border-color:#006fe6;color:#fff;padding:0 10px;margin-top:.31rem}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7);float:right;margin-left:5px;margin-right:-2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-selection--multiple.text-sm .select2-search.select2-search--inline .select2-search__field,.text-sm .select2-container--default .select2-selection--multiple .select2-search.select2-search--inline .select2-search__field{margin-top:8px}.select2-container--default .select2-selection--multiple.text-sm .select2-selection__choice,.text-sm .select2-container--default .select2-selection--multiple .select2-selection__choice{margin-top:.4rem}.select2-container--default.select2-container--focus .select2-selection--multiple,.select2-container--default.select2-container--focus .select2-selection--single{border-color:#80bdff}.select2-container--default.select2-container--focus .select2-search__field{border:0}.select2-container--default .select2-selection--single .select2-selection__rendered li{padding-right:10px}.input-group-prepend~.select2-container--default .select2-selection{border-bottom-left-radius:0;border-top-left-radius:0}.input-group>.select2-container--default:not(:last-child) .select2-selection{border-bottom-right-radius:0;border-top-right-radius:0}.select2-container--bootstrap4.select2-container--focus .select2-selection{box-shadow:none}select.form-control-sm~.select2-container--default{font-size:.875rem}.text-sm .select2-container--default .select2-selection--single,select.form-control-sm~.select2-container--default .select2-selection--single{height:calc(1.8125rem + 2px)}.text-sm .select2-container--default .select2-selection--single .select2-selection__rendered,select.form-control-sm~.select2-container--default .select2-selection--single .select2-selection__rendered{margin-top:-.4rem}.text-sm .select2-container--default .select2-selection--single .select2-selection__arrow,select.form-control-sm~.select2-container--default .select2-selection--single .select2-selection__arrow{top:-.12rem}.text-sm .select2-container--default .select2-selection--multiple,select.form-control-sm~.select2-container--default .select2-selection--multiple{min-height:calc(1.8125rem + 2px)}.text-sm .select2-container--default .select2-selection--multiple .select2-selection__rendered,select.form-control-sm~.select2-container--default .select2-selection--multiple .select2-selection__rendered{padding:0 .25rem .25rem;margin-top:-.1rem}.text-sm .select2-container--default .select2-selection--multiple .select2-selection__rendered li:first-child.select2-search.select2-search--inline,select.form-control-sm~.select2-container--default .select2-selection--multiple .select2-selection__rendered li:first-child.select2-search.select2-search--inline{margin-left:.25rem}.text-sm .select2-container--default .select2-selection--multiple .select2-selection__rendered .select2-search.select2-search--inline .select2-search__field,select.form-control-sm~.select2-container--default .select2-selection--multiple .select2-selection__rendered .select2-search.select2-search--inline .select2-search__field{margin-top:6px}.maximized-card .select2-dropdown{z-index:9999}.select2-primary+.select2-container--default.select2-container--focus .select2-selection--single,.select2-primary+.select2-container--default.select2-container--open .select2-selection--single{border-color:#80bdff}.select2-container--default .select2-primary.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-primary .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-primary .select2-search--inline .select2-search__field:focus,.select2-primary .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-primary .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-primary .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #80bdff}.select2-container--default .select2-primary .select2-results__option--highlighted,.select2-primary .select2-container--default .select2-results__option--highlighted{background-color:#007bff;color:#fff}.select2-container--default .select2-primary .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-primary .select2-results__option--highlighted[aria-selected]:hover,.select2-primary .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-primary .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#0074f0;color:#fff}.select2-container--default .select2-primary .select2-selection--multiple:focus,.select2-primary .select2-container--default .select2-selection--multiple:focus{border-color:#80bdff}.select2-container--default .select2-primary .select2-selection--multiple .select2-selection__choice,.select2-primary .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#007bff;border-color:#006fe6;color:#fff}.select2-container--default .select2-primary .select2-selection--multiple .select2-selection__choice__remove,.select2-primary .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-primary .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-primary .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-primary.select2-container--focus .select2-selection--multiple,.select2-primary .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#80bdff}.select2-secondary+.select2-container--default.select2-container--focus .select2-selection--single,.select2-secondary+.select2-container--default.select2-container--open .select2-selection--single{border-color:#afb5ba}.select2-container--default .select2-secondary.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-secondary .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-secondary .select2-search--inline .select2-search__field:focus,.select2-secondary .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-secondary .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-secondary .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #afb5ba}.select2-container--default .select2-secondary .select2-results__option--highlighted,.select2-secondary .select2-container--default .select2-results__option--highlighted{background-color:#6c757d;color:#fff}.select2-container--default .select2-secondary .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-secondary .select2-results__option--highlighted[aria-selected]:hover,.select2-secondary .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-secondary .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#656d75;color:#fff}.select2-container--default .select2-secondary .select2-selection--multiple:focus,.select2-secondary .select2-container--default .select2-selection--multiple:focus{border-color:#afb5ba}.select2-container--default .select2-secondary .select2-selection--multiple .select2-selection__choice,.select2-secondary .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#6c757d;border-color:#60686f;color:#fff}.select2-container--default .select2-secondary .select2-selection--multiple .select2-selection__choice__remove,.select2-secondary .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-secondary .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-secondary .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-secondary.select2-container--focus .select2-selection--multiple,.select2-secondary .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#afb5ba}.select2-success+.select2-container--default.select2-container--focus .select2-selection--single,.select2-success+.select2-container--default.select2-container--open .select2-selection--single{border-color:#71dd8a}.select2-container--default .select2-success.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-success .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-success .select2-search--inline .select2-search__field:focus,.select2-success .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-success .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-success .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #71dd8a}.select2-container--default .select2-success .select2-results__option--highlighted,.select2-success .select2-container--default .select2-results__option--highlighted{background-color:#28a745;color:#fff}.select2-container--default .select2-success .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-success .select2-results__option--highlighted[aria-selected]:hover,.select2-success .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-success .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#259b40;color:#fff}.select2-container--default .select2-success .select2-selection--multiple:focus,.select2-success .select2-container--default .select2-selection--multiple:focus{border-color:#71dd8a}.select2-container--default .select2-success .select2-selection--multiple .select2-selection__choice,.select2-success .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#28a745;border-color:#23923d;color:#fff}.select2-container--default .select2-success .select2-selection--multiple .select2-selection__choice__remove,.select2-success .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-success .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-success .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-success.select2-container--focus .select2-selection--multiple,.select2-success .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#71dd8a}.select2-info+.select2-container--default.select2-container--focus .select2-selection--single,.select2-info+.select2-container--default.select2-container--open .select2-selection--single{border-color:#63d9ec}.select2-container--default .select2-info.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-info .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-info .select2-search--inline .select2-search__field:focus,.select2-info .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-info .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-info .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #63d9ec}.select2-container--default .select2-info .select2-results__option--highlighted,.select2-info .select2-container--default .select2-results__option--highlighted{background-color:#17a2b8;color:#fff}.select2-container--default .select2-info .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-info .select2-results__option--highlighted[aria-selected]:hover,.select2-info .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-info .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#1596aa;color:#fff}.select2-container--default .select2-info .select2-selection--multiple:focus,.select2-info .select2-container--default .select2-selection--multiple:focus{border-color:#63d9ec}.select2-container--default .select2-info .select2-selection--multiple .select2-selection__choice,.select2-info .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#17a2b8;border-color:#148ea1;color:#fff}.select2-container--default .select2-info .select2-selection--multiple .select2-selection__choice__remove,.select2-info .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-info .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-info .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-info.select2-container--focus .select2-selection--multiple,.select2-info .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#63d9ec}.select2-warning+.select2-container--default.select2-container--focus .select2-selection--single,.select2-warning+.select2-container--default.select2-container--open .select2-selection--single{border-color:#ffe187}.select2-container--default .select2-warning.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-warning .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-warning .select2-search--inline .select2-search__field:focus,.select2-warning .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-warning .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-warning .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #ffe187}.select2-container--default .select2-warning .select2-results__option--highlighted,.select2-warning .select2-container--default .select2-results__option--highlighted{background-color:#ffc107;color:#1f2d3d}.select2-container--default .select2-warning .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-warning .select2-results__option--highlighted[aria-selected]:hover,.select2-warning .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-warning .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#f7b900;color:#1f2d3d}.select2-container--default .select2-warning .select2-selection--multiple:focus,.select2-warning .select2-container--default .select2-selection--multiple:focus{border-color:#ffe187}.select2-container--default .select2-warning .select2-selection--multiple .select2-selection__choice,.select2-warning .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#ffc107;border-color:#edb100;color:#1f2d3d}.select2-container--default .select2-warning .select2-selection--multiple .select2-selection__choice__remove,.select2-warning .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:rgba(31,45,61,.7)}.select2-container--default .select2-warning .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-warning .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#1f2d3d}.select2-container--default .select2-warning.select2-container--focus .select2-selection--multiple,.select2-warning .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#ffe187}.select2-danger+.select2-container--default.select2-container--focus .select2-selection--single,.select2-danger+.select2-container--default.select2-container--open .select2-selection--single{border-color:#efa2a9}.select2-container--default .select2-danger.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-danger .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-danger .select2-search--inline .select2-search__field:focus,.select2-danger .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-danger .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-danger .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #efa2a9}.select2-container--default .select2-danger .select2-results__option--highlighted,.select2-danger .select2-container--default .select2-results__option--highlighted{background-color:#dc3545;color:#fff}.select2-container--default .select2-danger .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-danger .select2-results__option--highlighted[aria-selected]:hover,.select2-danger .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-danger .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#da2839;color:#fff}.select2-container--default .select2-danger .select2-selection--multiple:focus,.select2-danger .select2-container--default .select2-selection--multiple:focus{border-color:#efa2a9}.select2-container--default .select2-danger .select2-selection--multiple .select2-selection__choice,.select2-danger .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#dc3545;border-color:#d32535;color:#fff}.select2-container--default .select2-danger .select2-selection--multiple .select2-selection__choice__remove,.select2-danger .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-danger .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-danger .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-danger.select2-container--focus .select2-selection--multiple,.select2-danger .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#efa2a9}.select2-light+.select2-container--default.select2-container--focus .select2-selection--single,.select2-light+.select2-container--default.select2-container--open .select2-selection--single{border-color:#fff}.select2-container--default .select2-light.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-light .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-light .select2-search--inline .select2-search__field:focus,.select2-light .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-light .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-light .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #fff}.select2-container--default .select2-light .select2-results__option--highlighted,.select2-light .select2-container--default .select2-results__option--highlighted{background-color:#f8f9fa;color:#1f2d3d}.select2-container--default .select2-light .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-light .select2-results__option--highlighted[aria-selected]:hover,.select2-light .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-light .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#eff1f4;color:#1f2d3d}.select2-container--default .select2-light .select2-selection--multiple:focus,.select2-light .select2-container--default .select2-selection--multiple:focus{border-color:#fff}.select2-container--default .select2-light .select2-selection--multiple .select2-selection__choice,.select2-light .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#f8f9fa;border-color:#e9ecef;color:#1f2d3d}.select2-container--default .select2-light .select2-selection--multiple .select2-selection__choice__remove,.select2-light .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:rgba(31,45,61,.7)}.select2-container--default .select2-light .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-light .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#1f2d3d}.select2-container--default .select2-light.select2-container--focus .select2-selection--multiple,.select2-light .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#fff}.select2-dark+.select2-container--default.select2-container--focus .select2-selection--single,.select2-dark+.select2-container--default.select2-container--open .select2-selection--single{border-color:#6d7a86}.select2-container--default .select2-dark.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-dark .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-dark .select2-search--inline .select2-search__field:focus,.select2-dark .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-dark .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-dark .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #6d7a86}.select2-container--default .select2-dark .select2-results__option--highlighted,.select2-dark .select2-container--default .select2-results__option--highlighted{background-color:#343a40;color:#fff}.select2-container--default .select2-dark .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-dark .select2-results__option--highlighted[aria-selected]:hover,.select2-dark .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-dark .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#2d3238;color:#fff}.select2-container--default .select2-dark .select2-selection--multiple:focus,.select2-dark .select2-container--default .select2-selection--multiple:focus{border-color:#6d7a86}.select2-container--default .select2-dark .select2-selection--multiple .select2-selection__choice,.select2-dark .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#343a40;border-color:#292d32;color:#fff}.select2-container--default .select2-dark .select2-selection--multiple .select2-selection__choice__remove,.select2-dark .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-dark .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-dark .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-dark.select2-container--focus .select2-selection--multiple,.select2-dark .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#6d7a86}.select2-lightblue+.select2-container--default.select2-container--focus .select2-selection--single,.select2-lightblue+.select2-container--default.select2-container--open .select2-selection--single{border-color:#99c5de}.select2-container--default .select2-lightblue.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-lightblue .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-lightblue .select2-search--inline .select2-search__field:focus,.select2-lightblue .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-lightblue .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-lightblue .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #99c5de}.select2-container--default .select2-lightblue .select2-results__option--highlighted,.select2-lightblue .select2-container--default .select2-results__option--highlighted{background-color:#3c8dbc;color:#fff}.select2-container--default .select2-lightblue .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-lightblue .select2-results__option--highlighted[aria-selected]:hover,.select2-lightblue .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-lightblue .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#3884b0;color:#fff}.select2-container--default .select2-lightblue .select2-selection--multiple:focus,.select2-lightblue .select2-container--default .select2-selection--multiple:focus{border-color:#99c5de}.select2-container--default .select2-lightblue .select2-selection--multiple .select2-selection__choice,.select2-lightblue .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3c8dbc;border-color:#367fa9;color:#fff}.select2-container--default .select2-lightblue .select2-selection--multiple .select2-selection__choice__remove,.select2-lightblue .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-lightblue .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-lightblue .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-lightblue.select2-container--focus .select2-selection--multiple,.select2-lightblue .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#99c5de}.select2-navy+.select2-container--default.select2-container--focus .select2-selection--single,.select2-navy+.select2-container--default.select2-container--open .select2-selection--single{border-color:#005ebf}.select2-container--default .select2-navy.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-navy .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-navy .select2-search--inline .select2-search__field:focus,.select2-navy .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-navy .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-navy .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #005ebf}.select2-container--default .select2-navy .select2-results__option--highlighted,.select2-navy .select2-container--default .select2-results__option--highlighted{background-color:#001f3f;color:#fff}.select2-container--default .select2-navy .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-navy .select2-results__option--highlighted[aria-selected]:hover,.select2-navy .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-navy .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#001730;color:#fff}.select2-container--default .select2-navy .select2-selection--multiple:focus,.select2-navy .select2-container--default .select2-selection--multiple:focus{border-color:#005ebf}.select2-container--default .select2-navy .select2-selection--multiple .select2-selection__choice,.select2-navy .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#001f3f;border-color:#001226;color:#fff}.select2-container--default .select2-navy .select2-selection--multiple .select2-selection__choice__remove,.select2-navy .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-navy .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-navy .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-navy.select2-container--focus .select2-selection--multiple,.select2-navy .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#005ebf}.select2-olive+.select2-container--default.select2-container--focus .select2-selection--single,.select2-olive+.select2-container--default.select2-container--open .select2-selection--single{border-color:#87cfaf}.select2-container--default .select2-olive.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-olive .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-olive .select2-search--inline .select2-search__field:focus,.select2-olive .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-olive .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-olive .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #87cfaf}.select2-container--default .select2-olive .select2-results__option--highlighted,.select2-olive .select2-container--default .select2-results__option--highlighted{background-color:#3d9970;color:#fff}.select2-container--default .select2-olive .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-olive .select2-results__option--highlighted[aria-selected]:hover,.select2-olive .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-olive .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#398e68;color:#fff}.select2-container--default .select2-olive .select2-selection--multiple:focus,.select2-olive .select2-container--default .select2-selection--multiple:focus{border-color:#87cfaf}.select2-container--default .select2-olive .select2-selection--multiple .select2-selection__choice,.select2-olive .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#3d9970;border-color:#368763;color:#fff}.select2-container--default .select2-olive .select2-selection--multiple .select2-selection__choice__remove,.select2-olive .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-olive .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-olive .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-olive.select2-container--focus .select2-selection--multiple,.select2-olive .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#87cfaf}.select2-lime+.select2-container--default.select2-container--focus .select2-selection--single,.select2-lime+.select2-container--default.select2-container--open .select2-selection--single{border-color:#81ffb8}.select2-container--default .select2-lime.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-lime .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-lime .select2-search--inline .select2-search__field:focus,.select2-lime .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-lime .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-lime .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #81ffb8}.select2-container--default .select2-lime .select2-results__option--highlighted,.select2-lime .select2-container--default .select2-results__option--highlighted{background-color:#01ff70;color:#1f2d3d}.select2-container--default .select2-lime .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-lime .select2-results__option--highlighted[aria-selected]:hover,.select2-lime .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-lime .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#00f169;color:#1f2d3d}.select2-container--default .select2-lime .select2-selection--multiple:focus,.select2-lime .select2-container--default .select2-selection--multiple:focus{border-color:#81ffb8}.select2-container--default .select2-lime .select2-selection--multiple .select2-selection__choice,.select2-lime .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#01ff70;border-color:#00e765;color:#1f2d3d}.select2-container--default .select2-lime .select2-selection--multiple .select2-selection__choice__remove,.select2-lime .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:rgba(31,45,61,.7)}.select2-container--default .select2-lime .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-lime .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#1f2d3d}.select2-container--default .select2-lime.select2-container--focus .select2-selection--multiple,.select2-lime .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#81ffb8}.select2-fuchsia+.select2-container--default.select2-container--focus .select2-selection--single,.select2-fuchsia+.select2-container--default.select2-container--open .select2-selection--single{border-color:#f88adf}.select2-container--default .select2-fuchsia.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-fuchsia .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-fuchsia .select2-search--inline .select2-search__field:focus,.select2-fuchsia .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-fuchsia .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-fuchsia .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #f88adf}.select2-container--default .select2-fuchsia .select2-results__option--highlighted,.select2-fuchsia .select2-container--default .select2-results__option--highlighted{background-color:#f012be;color:#fff}.select2-container--default .select2-fuchsia .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-fuchsia .select2-results__option--highlighted[aria-selected]:hover,.select2-fuchsia .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-fuchsia .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#e40eb4;color:#fff}.select2-container--default .select2-fuchsia .select2-selection--multiple:focus,.select2-fuchsia .select2-container--default .select2-selection--multiple:focus{border-color:#f88adf}.select2-container--default .select2-fuchsia .select2-selection--multiple .select2-selection__choice,.select2-fuchsia .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#f012be;border-color:#db0ead;color:#fff}.select2-container--default .select2-fuchsia .select2-selection--multiple .select2-selection__choice__remove,.select2-fuchsia .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-fuchsia .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-fuchsia .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-fuchsia.select2-container--focus .select2-selection--multiple,.select2-fuchsia .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#f88adf}.select2-maroon+.select2-container--default.select2-container--focus .select2-selection--single,.select2-maroon+.select2-container--default.select2-container--open .select2-selection--single{border-color:#f083ab}.select2-container--default .select2-maroon.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-maroon .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-maroon .select2-search--inline .select2-search__field:focus,.select2-maroon .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-maroon .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-maroon .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #f083ab}.select2-container--default .select2-maroon .select2-results__option--highlighted,.select2-maroon .select2-container--default .select2-results__option--highlighted{background-color:#d81b60;color:#fff}.select2-container--default .select2-maroon .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-maroon .select2-results__option--highlighted[aria-selected]:hover,.select2-maroon .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-maroon .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#ca195a;color:#fff}.select2-container--default .select2-maroon .select2-selection--multiple:focus,.select2-maroon .select2-container--default .select2-selection--multiple:focus{border-color:#f083ab}.select2-container--default .select2-maroon .select2-selection--multiple .select2-selection__choice,.select2-maroon .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#d81b60;border-color:#c11856;color:#fff}.select2-container--default .select2-maroon .select2-selection--multiple .select2-selection__choice__remove,.select2-maroon .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-maroon .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-maroon .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-maroon.select2-container--focus .select2-selection--multiple,.select2-maroon .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#f083ab}.select2-blue+.select2-container--default.select2-container--focus .select2-selection--single,.select2-blue+.select2-container--default.select2-container--open .select2-selection--single{border-color:#80bdff}.select2-blue .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-blue .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-blue .select2-container--default .select2-search--inline .select2-search__field:focus,.select2-container--default .select2-blue.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-blue .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-blue .select2-search--inline .select2-search__field:focus{border:1px solid #80bdff}.select2-blue .select2-container--default .select2-results__option--highlighted,.select2-container--default .select2-blue .select2-results__option--highlighted{background-color:#007bff;color:#fff}.select2-blue .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-blue .select2-container--default .select2-results__option--highlighted[aria-selected]:hover,.select2-container--default .select2-blue .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-blue .select2-results__option--highlighted[aria-selected]:hover{background-color:#0074f0;color:#fff}.select2-blue .select2-container--default .select2-selection--multiple:focus,.select2-container--default .select2-blue .select2-selection--multiple:focus{border-color:#80bdff}.select2-blue .select2-container--default .select2-selection--multiple .select2-selection__choice,.select2-container--default .select2-blue .select2-selection--multiple .select2-selection__choice{background-color:#007bff;border-color:#006fe6;color:#fff}.select2-blue .select2-container--default .select2-selection--multiple .select2-selection__choice__remove,.select2-container--default .select2-blue .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-blue .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-container--default .select2-blue .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-blue .select2-container--default.select2-container--focus .select2-selection--multiple,.select2-container--default .select2-blue.select2-container--focus .select2-selection--multiple{border-color:#80bdff}.select2-indigo+.select2-container--default.select2-container--focus .select2-selection--single,.select2-indigo+.select2-container--default.select2-container--open .select2-selection--single{border-color:#b389f9}.select2-container--default .select2-indigo.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-indigo .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-indigo .select2-search--inline .select2-search__field:focus,.select2-indigo .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-indigo .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-indigo .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #b389f9}.select2-container--default .select2-indigo .select2-results__option--highlighted,.select2-indigo .select2-container--default .select2-results__option--highlighted{background-color:#6610f2;color:#fff}.select2-container--default .select2-indigo .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-indigo .select2-results__option--highlighted[aria-selected]:hover,.select2-indigo .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-indigo .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#5f0de6;color:#fff}.select2-container--default .select2-indigo .select2-selection--multiple:focus,.select2-indigo .select2-container--default .select2-selection--multiple:focus{border-color:#b389f9}.select2-container--default .select2-indigo .select2-selection--multiple .select2-selection__choice,.select2-indigo .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#6610f2;border-color:#5b0cdd;color:#fff}.select2-container--default .select2-indigo .select2-selection--multiple .select2-selection__choice__remove,.select2-indigo .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-indigo .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-indigo .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-indigo.select2-container--focus .select2-selection--multiple,.select2-indigo .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#b389f9}.select2-purple+.select2-container--default.select2-container--focus .select2-selection--single,.select2-purple+.select2-container--default.select2-container--open .select2-selection--single{border-color:#b8a2e0}.select2-container--default .select2-purple.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-purple .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-purple .select2-search--inline .select2-search__field:focus,.select2-purple .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-purple .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-purple .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #b8a2e0}.select2-container--default .select2-purple .select2-results__option--highlighted,.select2-purple .select2-container--default .select2-results__option--highlighted{background-color:#6f42c1;color:#fff}.select2-container--default .select2-purple .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-purple .select2-results__option--highlighted[aria-selected]:hover,.select2-purple .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-purple .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#683cb8;color:#fff}.select2-container--default .select2-purple .select2-selection--multiple:focus,.select2-purple .select2-container--default .select2-selection--multiple:focus{border-color:#b8a2e0}.select2-container--default .select2-purple .select2-selection--multiple .select2-selection__choice,.select2-purple .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#6f42c1;border-color:#643ab0;color:#fff}.select2-container--default .select2-purple .select2-selection--multiple .select2-selection__choice__remove,.select2-purple .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-purple .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-purple .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-purple.select2-container--focus .select2-selection--multiple,.select2-purple .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#b8a2e0}.select2-pink+.select2-container--default.select2-container--focus .select2-selection--single,.select2-pink+.select2-container--default.select2-container--open .select2-selection--single{border-color:#f6b0d0}.select2-container--default .select2-pink.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-pink .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-pink .select2-search--inline .select2-search__field:focus,.select2-pink .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-pink .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-pink .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #f6b0d0}.select2-container--default .select2-pink .select2-results__option--highlighted,.select2-pink .select2-container--default .select2-results__option--highlighted{background-color:#e83e8c;color:#fff}.select2-container--default .select2-pink .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-pink .select2-results__option--highlighted[aria-selected]:hover,.select2-pink .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-pink .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#e63084;color:#fff}.select2-container--default .select2-pink .select2-selection--multiple:focus,.select2-pink .select2-container--default .select2-selection--multiple:focus{border-color:#f6b0d0}.select2-container--default .select2-pink .select2-selection--multiple .select2-selection__choice,.select2-pink .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e83e8c;border-color:#e5277e;color:#fff}.select2-container--default .select2-pink .select2-selection--multiple .select2-selection__choice__remove,.select2-pink .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-pink .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-pink .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-pink.select2-container--focus .select2-selection--multiple,.select2-pink .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#f6b0d0}.select2-red+.select2-container--default.select2-container--focus .select2-selection--single,.select2-red+.select2-container--default.select2-container--open .select2-selection--single{border-color:#efa2a9}.select2-container--default .select2-red.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-red .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-red .select2-search--inline .select2-search__field:focus,.select2-red .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-red .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-red .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #efa2a9}.select2-container--default .select2-red .select2-results__option--highlighted,.select2-red .select2-container--default .select2-results__option--highlighted{background-color:#dc3545;color:#fff}.select2-container--default .select2-red .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-red .select2-results__option--highlighted[aria-selected]:hover,.select2-red .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-red .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#da2839;color:#fff}.select2-container--default .select2-red .select2-selection--multiple:focus,.select2-red .select2-container--default .select2-selection--multiple:focus{border-color:#efa2a9}.select2-container--default .select2-red .select2-selection--multiple .select2-selection__choice,.select2-red .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#dc3545;border-color:#d32535;color:#fff}.select2-container--default .select2-red .select2-selection--multiple .select2-selection__choice__remove,.select2-red .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-red .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-red .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-red.select2-container--focus .select2-selection--multiple,.select2-red .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#efa2a9}.select2-orange+.select2-container--default.select2-container--focus .select2-selection--single,.select2-orange+.select2-container--default.select2-container--open .select2-selection--single{border-color:#fec392}.select2-container--default .select2-orange.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-orange .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-orange .select2-search--inline .select2-search__field:focus,.select2-orange .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-orange .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-orange .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #fec392}.select2-container--default .select2-orange .select2-results__option--highlighted,.select2-orange .select2-container--default .select2-results__option--highlighted{background-color:#fd7e14;color:#1f2d3d}.select2-container--default .select2-orange .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-orange .select2-results__option--highlighted[aria-selected]:hover,.select2-orange .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-orange .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#fd7605;color:#fff}.select2-container--default .select2-orange .select2-selection--multiple:focus,.select2-orange .select2-container--default .select2-selection--multiple:focus{border-color:#fec392}.select2-container--default .select2-orange .select2-selection--multiple .select2-selection__choice,.select2-orange .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#fd7e14;border-color:#f57102;color:#1f2d3d}.select2-container--default .select2-orange .select2-selection--multiple .select2-selection__choice__remove,.select2-orange .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:rgba(31,45,61,.7)}.select2-container--default .select2-orange .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-orange .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#1f2d3d}.select2-container--default .select2-orange.select2-container--focus .select2-selection--multiple,.select2-orange .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#fec392}.select2-yellow+.select2-container--default.select2-container--focus .select2-selection--single,.select2-yellow+.select2-container--default.select2-container--open .select2-selection--single{border-color:#ffe187}.select2-container--default .select2-yellow.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-yellow .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-yellow .select2-search--inline .select2-search__field:focus,.select2-yellow .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-yellow .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-yellow .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #ffe187}.select2-container--default .select2-yellow .select2-results__option--highlighted,.select2-yellow .select2-container--default .select2-results__option--highlighted{background-color:#ffc107;color:#1f2d3d}.select2-container--default .select2-yellow .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-yellow .select2-results__option--highlighted[aria-selected]:hover,.select2-yellow .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-yellow .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#f7b900;color:#1f2d3d}.select2-container--default .select2-yellow .select2-selection--multiple:focus,.select2-yellow .select2-container--default .select2-selection--multiple:focus{border-color:#ffe187}.select2-container--default .select2-yellow .select2-selection--multiple .select2-selection__choice,.select2-yellow .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#ffc107;border-color:#edb100;color:#1f2d3d}.select2-container--default .select2-yellow .select2-selection--multiple .select2-selection__choice__remove,.select2-yellow .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:rgba(31,45,61,.7)}.select2-container--default .select2-yellow .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-yellow .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#1f2d3d}.select2-container--default .select2-yellow.select2-container--focus .select2-selection--multiple,.select2-yellow .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#ffe187}.select2-green+.select2-container--default.select2-container--focus .select2-selection--single,.select2-green+.select2-container--default.select2-container--open .select2-selection--single{border-color:#71dd8a}.select2-container--default .select2-green.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-green .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-green .select2-search--inline .select2-search__field:focus,.select2-green .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-green .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-green .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #71dd8a}.select2-container--default .select2-green .select2-results__option--highlighted,.select2-green .select2-container--default .select2-results__option--highlighted{background-color:#28a745;color:#fff}.select2-container--default .select2-green .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-green .select2-results__option--highlighted[aria-selected]:hover,.select2-green .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-green .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#259b40;color:#fff}.select2-container--default .select2-green .select2-selection--multiple:focus,.select2-green .select2-container--default .select2-selection--multiple:focus{border-color:#71dd8a}.select2-container--default .select2-green .select2-selection--multiple .select2-selection__choice,.select2-green .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#28a745;border-color:#23923d;color:#fff}.select2-container--default .select2-green .select2-selection--multiple .select2-selection__choice__remove,.select2-green .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-green .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-green .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-green.select2-container--focus .select2-selection--multiple,.select2-green .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#71dd8a}.select2-teal+.select2-container--default.select2-container--focus .select2-selection--single,.select2-teal+.select2-container--default.select2-container--open .select2-selection--single{border-color:#7eeaca}.select2-container--default .select2-teal.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-teal .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-teal .select2-search--inline .select2-search__field:focus,.select2-teal .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-teal .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-teal .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #7eeaca}.select2-container--default .select2-teal .select2-results__option--highlighted,.select2-teal .select2-container--default .select2-results__option--highlighted{background-color:#20c997;color:#fff}.select2-container--default .select2-teal .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-teal .select2-results__option--highlighted[aria-selected]:hover,.select2-teal .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-teal .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#1ebc8d;color:#fff}.select2-container--default .select2-teal .select2-selection--multiple:focus,.select2-teal .select2-container--default .select2-selection--multiple:focus{border-color:#7eeaca}.select2-container--default .select2-teal .select2-selection--multiple .select2-selection__choice,.select2-teal .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#20c997;border-color:#1cb386;color:#fff}.select2-container--default .select2-teal .select2-selection--multiple .select2-selection__choice__remove,.select2-teal .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-teal .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-teal .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-teal.select2-container--focus .select2-selection--multiple,.select2-teal .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#7eeaca}.select2-cyan+.select2-container--default.select2-container--focus .select2-selection--single,.select2-cyan+.select2-container--default.select2-container--open .select2-selection--single{border-color:#63d9ec}.select2-container--default .select2-cyan.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-cyan .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-cyan .select2-search--inline .select2-search__field:focus,.select2-cyan .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-cyan .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-cyan .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #63d9ec}.select2-container--default .select2-cyan .select2-results__option--highlighted,.select2-cyan .select2-container--default .select2-results__option--highlighted{background-color:#17a2b8;color:#fff}.select2-container--default .select2-cyan .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-cyan .select2-results__option--highlighted[aria-selected]:hover,.select2-cyan .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-cyan .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#1596aa;color:#fff}.select2-container--default .select2-cyan .select2-selection--multiple:focus,.select2-cyan .select2-container--default .select2-selection--multiple:focus{border-color:#63d9ec}.select2-container--default .select2-cyan .select2-selection--multiple .select2-selection__choice,.select2-cyan .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#17a2b8;border-color:#148ea1;color:#fff}.select2-container--default .select2-cyan .select2-selection--multiple .select2-selection__choice__remove,.select2-cyan .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-cyan .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-cyan .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-cyan.select2-container--focus .select2-selection--multiple,.select2-cyan .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#63d9ec}.select2-white+.select2-container--default.select2-container--focus .select2-selection--single,.select2-white+.select2-container--default.select2-container--open .select2-selection--single{border-color:#fff}.select2-container--default .select2-white.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-white .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-white .select2-search--inline .select2-search__field:focus,.select2-white .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-white .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-white .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #fff}.select2-container--default .select2-white .select2-results__option--highlighted,.select2-white .select2-container--default .select2-results__option--highlighted{background-color:#fff;color:#1f2d3d}.select2-container--default .select2-white .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-white .select2-results__option--highlighted[aria-selected]:hover,.select2-white .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-white .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#f7f7f7;color:#1f2d3d}.select2-container--default .select2-white .select2-selection--multiple:focus,.select2-white .select2-container--default .select2-selection--multiple:focus{border-color:#fff}.select2-container--default .select2-white .select2-selection--multiple .select2-selection__choice,.select2-white .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#fff;border-color:#f2f2f2;color:#1f2d3d}.select2-container--default .select2-white .select2-selection--multiple .select2-selection__choice__remove,.select2-white .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:rgba(31,45,61,.7)}.select2-container--default .select2-white .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-white .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#1f2d3d}.select2-container--default .select2-white.select2-container--focus .select2-selection--multiple,.select2-white .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#fff}.select2-gray+.select2-container--default.select2-container--focus .select2-selection--single,.select2-gray+.select2-container--default.select2-container--open .select2-selection--single{border-color:#afb5ba}.select2-container--default .select2-gray.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-gray .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-gray .select2-search--inline .select2-search__field:focus,.select2-gray .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-gray .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-gray .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #afb5ba}.select2-container--default .select2-gray .select2-results__option--highlighted,.select2-gray .select2-container--default .select2-results__option--highlighted{background-color:#6c757d;color:#fff}.select2-container--default .select2-gray .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-gray .select2-results__option--highlighted[aria-selected]:hover,.select2-gray .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-gray .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#656d75;color:#fff}.select2-container--default .select2-gray .select2-selection--multiple:focus,.select2-gray .select2-container--default .select2-selection--multiple:focus{border-color:#afb5ba}.select2-container--default .select2-gray .select2-selection--multiple .select2-selection__choice,.select2-gray .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#6c757d;border-color:#60686f;color:#fff}.select2-container--default .select2-gray .select2-selection--multiple .select2-selection__choice__remove,.select2-gray .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-gray .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-gray .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-gray.select2-container--focus .select2-selection--multiple,.select2-gray .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#afb5ba}.select2-gray-dark+.select2-container--default.select2-container--focus .select2-selection--single,.select2-gray-dark+.select2-container--default.select2-container--open .select2-selection--single{border-color:#6d7a86}.select2-container--default .select2-gray-dark.select2-dropdown .select2-search__field:focus,.select2-container--default .select2-gray-dark .select2-dropdown .select2-search__field:focus,.select2-container--default .select2-gray-dark .select2-search--inline .select2-search__field:focus,.select2-gray-dark .select2-container--default.select2-dropdown .select2-search__field:focus,.select2-gray-dark .select2-container--default .select2-dropdown .select2-search__field:focus,.select2-gray-dark .select2-container--default .select2-search--inline .select2-search__field:focus{border:1px solid #6d7a86}.select2-container--default .select2-gray-dark .select2-results__option--highlighted,.select2-gray-dark .select2-container--default .select2-results__option--highlighted{background-color:#343a40;color:#fff}.select2-container--default .select2-gray-dark .select2-results__option--highlighted[aria-selected],.select2-container--default .select2-gray-dark .select2-results__option--highlighted[aria-selected]:hover,.select2-gray-dark .select2-container--default .select2-results__option--highlighted[aria-selected],.select2-gray-dark .select2-container--default .select2-results__option--highlighted[aria-selected]:hover{background-color:#2d3238;color:#fff}.select2-container--default .select2-gray-dark .select2-selection--multiple:focus,.select2-gray-dark .select2-container--default .select2-selection--multiple:focus{border-color:#6d7a86}.select2-container--default .select2-gray-dark .select2-selection--multiple .select2-selection__choice,.select2-gray-dark .select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#343a40;border-color:#292d32;color:#fff}.select2-container--default .select2-gray-dark .select2-selection--multiple .select2-selection__choice__remove,.select2-gray-dark .select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:hsla(0,0%,100%,.7)}.select2-container--default .select2-gray-dark .select2-selection--multiple .select2-selection__choice__remove:hover,.select2-gray-dark .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#fff}.select2-container--default .select2-gray-dark.select2-container--focus .select2-selection--multiple,.select2-gray-dark .select2-container--default.select2-container--focus .select2-selection--multiple{border-color:#6d7a86}.slider .tooltip.in{opacity:.9}.slider.slider-vertical{height:100%}.slider.slider-horizontal{width:100%}.slider-primary .slider .slider-selection{background:#007bff}.slider-secondary .slider .slider-selection{background:#6c757d}.slider-success .slider .slider-selection{background:#28a745}.slider-info .slider .slider-selection{background:#17a2b8}.slider-warning .slider .slider-selection{background:#ffc107}.slider-danger .slider .slider-selection{background:#dc3545}.slider-light .slider .slider-selection{background:#f8f9fa}.slider-dark .slider .slider-selection{background:#343a40}.slider-lightblue .slider .slider-selection{background:#3c8dbc}.slider-navy .slider .slider-selection{background:#001f3f}.slider-olive .slider .slider-selection{background:#3d9970}.slider-lime .slider .slider-selection{background:#01ff70}.slider-fuchsia .slider .slider-selection{background:#f012be}.slider-maroon .slider .slider-selection{background:#d81b60}.slider-blue .slider .slider-selection{background:#007bff}.slider-indigo .slider .slider-selection{background:#6610f2}.slider-purple .slider .slider-selection{background:#6f42c1}.slider-pink .slider .slider-selection{background:#e83e8c}.slider-red .slider .slider-selection{background:#dc3545}.slider-orange .slider .slider-selection{background:#fd7e14}.slider-yellow .slider .slider-selection{background:#ffc107}.slider-green .slider .slider-selection{background:#28a745}.slider-teal .slider .slider-selection{background:#20c997}.slider-cyan .slider .slider-selection{background:#17a2b8}.slider-white .slider .slider-selection{background:#fff}.slider-gray .slider .slider-selection{background:#6c757d}.slider-gray-dark .slider .slider-selection{background:#343a40}.icheck-primary>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-primary>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-primary>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-primary>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#007bff}.icheck-primary>input:first-child:checked+input[type=hidden]+label:before,.icheck-primary>input:first-child:checked+label:before{background-color:#007bff;border-color:#007bff}.icheck-secondary>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-secondary>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-secondary>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-secondary>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#6c757d}.icheck-secondary>input:first-child:checked+input[type=hidden]+label:before,.icheck-secondary>input:first-child:checked+label:before{background-color:#6c757d;border-color:#6c757d}.icheck-success>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-success>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-success>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-success>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#28a745}.icheck-success>input:first-child:checked+input[type=hidden]+label:before,.icheck-success>input:first-child:checked+label:before{background-color:#28a745;border-color:#28a745}.icheck-info>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-info>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-info>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-info>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#17a2b8}.icheck-info>input:first-child:checked+input[type=hidden]+label:before,.icheck-info>input:first-child:checked+label:before{background-color:#17a2b8;border-color:#17a2b8}.icheck-warning>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-warning>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-warning>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-warning>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#ffc107}.icheck-warning>input:first-child:checked+input[type=hidden]+label:before,.icheck-warning>input:first-child:checked+label:before{background-color:#ffc107;border-color:#ffc107}.icheck-danger>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-danger>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-danger>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-danger>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#dc3545}.icheck-danger>input:first-child:checked+input[type=hidden]+label:before,.icheck-danger>input:first-child:checked+label:before{background-color:#dc3545;border-color:#dc3545}.icheck-light>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-light>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-light>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-light>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#f8f9fa}.icheck-light>input:first-child:checked+input[type=hidden]+label:before,.icheck-light>input:first-child:checked+label:before{background-color:#f8f9fa;border-color:#f8f9fa}.icheck-dark>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-dark>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-dark>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-dark>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#343a40}.icheck-dark>input:first-child:checked+input[type=hidden]+label:before,.icheck-dark>input:first-child:checked+label:before{background-color:#343a40;border-color:#343a40}.icheck-lightblue>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-lightblue>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-lightblue>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-lightblue>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#3c8dbc}.icheck-lightblue>input:first-child:checked+input[type=hidden]+label:before,.icheck-lightblue>input:first-child:checked+label:before{background-color:#3c8dbc;border-color:#3c8dbc}.icheck-navy>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-navy>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-navy>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-navy>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#001f3f}.icheck-navy>input:first-child:checked+input[type=hidden]+label:before,.icheck-navy>input:first-child:checked+label:before{background-color:#001f3f;border-color:#001f3f}.icheck-olive>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-olive>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-olive>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-olive>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#3d9970}.icheck-olive>input:first-child:checked+input[type=hidden]+label:before,.icheck-olive>input:first-child:checked+label:before{background-color:#3d9970;border-color:#3d9970}.icheck-lime>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-lime>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-lime>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-lime>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#01ff70}.icheck-lime>input:first-child:checked+input[type=hidden]+label:before,.icheck-lime>input:first-child:checked+label:before{background-color:#01ff70;border-color:#01ff70}.icheck-fuchsia>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-fuchsia>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-fuchsia>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-fuchsia>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#f012be}.icheck-fuchsia>input:first-child:checked+input[type=hidden]+label:before,.icheck-fuchsia>input:first-child:checked+label:before{background-color:#f012be;border-color:#f012be}.icheck-maroon>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-maroon>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-maroon>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-maroon>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#d81b60}.icheck-maroon>input:first-child:checked+input[type=hidden]+label:before,.icheck-maroon>input:first-child:checked+label:before{background-color:#d81b60;border-color:#d81b60}.icheck-blue>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-blue>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-blue>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-blue>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#007bff}.icheck-blue>input:first-child:checked+input[type=hidden]+label:before,.icheck-blue>input:first-child:checked+label:before{background-color:#007bff;border-color:#007bff}.icheck-indigo>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-indigo>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-indigo>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-indigo>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#6610f2}.icheck-indigo>input:first-child:checked+input[type=hidden]+label:before,.icheck-indigo>input:first-child:checked+label:before{background-color:#6610f2;border-color:#6610f2}.icheck-purple>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-purple>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-purple>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-purple>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#6f42c1}.icheck-purple>input:first-child:checked+input[type=hidden]+label:before,.icheck-purple>input:first-child:checked+label:before{background-color:#6f42c1;border-color:#6f42c1}.icheck-pink>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-pink>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-pink>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-pink>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#e83e8c}.icheck-pink>input:first-child:checked+input[type=hidden]+label:before,.icheck-pink>input:first-child:checked+label:before{background-color:#e83e8c;border-color:#e83e8c}.icheck-red>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-red>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-red>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-red>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#dc3545}.icheck-red>input:first-child:checked+input[type=hidden]+label:before,.icheck-red>input:first-child:checked+label:before{background-color:#dc3545;border-color:#dc3545}.icheck-orange>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-orange>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-orange>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-orange>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#fd7e14}.icheck-orange>input:first-child:checked+input[type=hidden]+label:before,.icheck-orange>input:first-child:checked+label:before{background-color:#fd7e14;border-color:#fd7e14}.icheck-yellow>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-yellow>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-yellow>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-yellow>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#ffc107}.icheck-yellow>input:first-child:checked+input[type=hidden]+label:before,.icheck-yellow>input:first-child:checked+label:before{background-color:#ffc107;border-color:#ffc107}.icheck-green>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-green>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-green>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-green>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#28a745}.icheck-green>input:first-child:checked+input[type=hidden]+label:before,.icheck-green>input:first-child:checked+label:before{background-color:#28a745;border-color:#28a745}.icheck-teal>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-teal>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-teal>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-teal>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#20c997}.icheck-teal>input:first-child:checked+input[type=hidden]+label:before,.icheck-teal>input:first-child:checked+label:before{background-color:#20c997;border-color:#20c997}.icheck-cyan>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-cyan>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-cyan>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-cyan>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#17a2b8}.icheck-cyan>input:first-child:checked+input[type=hidden]+label:before,.icheck-cyan>input:first-child:checked+label:before{background-color:#17a2b8;border-color:#17a2b8}.icheck-white>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-white>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-white>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-white>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#fff}.icheck-white>input:first-child:checked+input[type=hidden]+label:before,.icheck-white>input:first-child:checked+label:before{background-color:#fff;border-color:#fff}.icheck-gray>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-gray>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-gray>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-gray>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#6c757d}.icheck-gray>input:first-child:checked+input[type=hidden]+label:before,.icheck-gray>input:first-child:checked+label:before{background-color:#6c757d;border-color:#6c757d}.icheck-gray-dark>input:first-child:not(:checked):not(:disabled):focus+input[type=hidden]+label:before,.icheck-gray-dark>input:first-child:not(:checked):not(:disabled):focus+label:before,.icheck-gray-dark>input:first-child:not(:checked):not(:disabled):hover+input[type=hidden]+label:before,.icheck-gray-dark>input:first-child:not(:checked):not(:disabled):hover+label:before{border-color:#343a40}.icheck-gray-dark>input:first-child:checked+input[type=hidden]+label:before,.icheck-gray-dark>input:first-child:checked+label:before{background-color:#343a40;border-color:#343a40}.mapael .map{position:relative}.mapael .mapTooltip{font-family:Source Sans Pro,-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji,Segoe UI Symbol;font-style:normal;font-weight:400;line-height:1.5;text-align:left;text-align:start;text-decoration:none;text-shadow:none;text-transform:none;letter-spacing:normal;word-break:normal;word-spacing:normal;white-space:normal;line-break:auto;border-radius:.25rem;font-size:.875rem;background-color:#000;color:#fff;display:block;max-width:200px;padding:.25rem .5rem;position:absolute;text-align:center;word-wrap:break-word;z-index:1070}.mapael .myLegend{background-color:#f8f9fa;border:1px solid #adb5bd;padding:10px;width:600px}.mapael .zoomButton{background-color:#f8f9fa;border:1px solid #ddd;border-radius:.25rem;color:#444;cursor:pointer;font-weight:700;height:16px;left:10px;line-height:14px;padding-left:1px;position:absolute;text-align:center;top:0;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;width:16px}.mapael .zoomButton.hover,.mapael .zoomButton:active,.mapael .zoomButton:hover{background-color:#e9ecef;color:#2b2b2b}.mapael .zoomReset{line-height:12px;top:10px}.mapael .zoomIn{top:30px}.mapael .zoomOut{top:50px}.jqvmap-zoomin,.jqvmap-zoomout{background-color:#f8f9fa;border:1px solid #ddd;border-radius:.25rem;color:#444;height:15px;width:15px}.jqvmap-zoomin.hover,.jqvmap-zoomin:active,.jqvmap-zoomin:hover,.jqvmap-zoomout.hover,.jqvmap-zoomout:active,.jqvmap-zoomout:hover{background-color:#e9ecef;color:#2b2b2b}.swal2-icon.swal2-info{border-color:ligthen(#17a2b8,20%);color:#17a2b8}.swal2-icon.swal2-warning{border-color:ligthen(#ffc107,20%);color:#ffc107}.swal2-icon.swal2-error{border-color:ligthen(#dc3545,20%);color:#dc3545}.swal2-icon.swal2-question{border-color:ligthen(#6c757d,20%);color:#6c757d}.swal2-icon.swal2-success{color:#28a745}.swal2-icon.swal2-success,.swal2-icon.swal2-success .swal2-success-ring{border-color:ligthen(#28a745,20%)}.swal2-icon.swal2-success [class^=swal2-success-line]{background-color:#28a745}#toast-container .toast{background-color:#007bff}#toast-container .toast-success{background-color:#28a745}#toast-container .toast-error{background-color:#dc3545}#toast-container .toast-info{background-color:#17a2b8}#toast-container .toast-warning{background-color:#ffc107}.toast-bottom-full-width .toast,.toast-top-full-width .toast{max-width:inherit}.pace{z-index:1048}.pace .pace-progress{z-index:1049}.pace .pace-activity{z-index:1050}.pace-primary .pace .pace-progress{background:#007bff}.pace-barber-shop-primary .pace{background:#fff}.pace-barber-shop-primary .pace .pace-progress{background:#007bff}.pace-barber-shop-primary .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-primary .pace .pace-progress:after{color:rgba(0,123,255,.2)}.pace-bounce-primary .pace .pace-activity{background:#007bff}.pace-center-atom-primary .pace-progress{height:100px;width:80px}.pace-center-atom-primary .pace-progress:before{background:#007bff;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-primary .pace-activity,.pace-center-atom-primary .pace-activity:after,.pace-center-atom-primary .pace-activity:before{border-color:#007bff}.pace-center-circle-primary .pace .pace-progress{background:rgba(0,123,255,.8);color:#fff}.pace-center-radar-primary .pace .pace-activity,.pace-center-radar-primary .pace .pace-activity:before{border-color:#007bff transparent transparent}.pace-center-simple-primary .pace{background:#fff;border-color:#007bff}.pace-center-simple-primary .pace .pace-progress{background:#007bff}.pace-material-primary .pace{color:#007bff}.pace-corner-indicator-primary .pace .pace-activity{background:#007bff}.pace-corner-indicator-primary .pace .pace-activity:after,.pace-corner-indicator-primary .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-primary .pace .pace-activity:before{border-right-color:rgba(0,123,255,.2);border-left-color:rgba(0,123,255,.2)}.pace-corner-indicator-primary .pace .pace-activity:after{border-top-color:rgba(0,123,255,.2);border-bottom-color:rgba(0,123,255,.2)}.pace-fill-left-primary .pace .pace-progress{background-color:rgba(0,123,255,.2)}.pace-flash-primary .pace .pace-progress{background:#007bff}.pace-flash-primary .pace .pace-progress-inner{box-shadow:0 0 10px #007bff,0 0 5px #007bff}.pace-flash-primary .pace .pace-activity{border-top-color:#007bff;border-left-color:#007bff}.pace-loading-bar-primary .pace .pace-progress{background:#007bff;color:#007bff;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-primary .pace .pace-activity{box-shadow:inset 0 0 0 2px #007bff,inset 0 0 0 7px #fff}.pace-mac-osx-primary .pace .pace-progress{background-color:#007bff;box-shadow:inset -1px 0 #007bff,inset 0 -1px #007bff,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-primary .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-primary .pace-progress{color:#007bff}.pace-secondary .pace .pace-progress{background:#6c757d}.pace-barber-shop-secondary .pace{background:#fff}.pace-barber-shop-secondary .pace .pace-progress{background:#6c757d}.pace-barber-shop-secondary .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-secondary .pace .pace-progress:after{color:rgba(108,117,125,.2)}.pace-bounce-secondary .pace .pace-activity{background:#6c757d}.pace-center-atom-secondary .pace-progress{height:100px;width:80px}.pace-center-atom-secondary .pace-progress:before{background:#6c757d;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-secondary .pace-activity,.pace-center-atom-secondary .pace-activity:after,.pace-center-atom-secondary .pace-activity:before{border-color:#6c757d}.pace-center-circle-secondary .pace .pace-progress{background:rgba(108,117,125,.8);color:#fff}.pace-center-radar-secondary .pace .pace-activity,.pace-center-radar-secondary .pace .pace-activity:before{border-color:#6c757d transparent transparent}.pace-center-simple-secondary .pace{background:#fff;border-color:#6c757d}.pace-center-simple-secondary .pace .pace-progress{background:#6c757d}.pace-material-secondary .pace{color:#6c757d}.pace-corner-indicator-secondary .pace .pace-activity{background:#6c757d}.pace-corner-indicator-secondary .pace .pace-activity:after,.pace-corner-indicator-secondary .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-secondary .pace .pace-activity:before{border-right-color:rgba(108,117,125,.2);border-left-color:rgba(108,117,125,.2)}.pace-corner-indicator-secondary .pace .pace-activity:after{border-top-color:rgba(108,117,125,.2);border-bottom-color:rgba(108,117,125,.2)}.pace-fill-left-secondary .pace .pace-progress{background-color:rgba(108,117,125,.2)}.pace-flash-secondary .pace .pace-progress{background:#6c757d}.pace-flash-secondary .pace .pace-progress-inner{box-shadow:0 0 10px #6c757d,0 0 5px #6c757d}.pace-flash-secondary .pace .pace-activity{border-top-color:#6c757d;border-left-color:#6c757d}.pace-loading-bar-secondary .pace .pace-progress{background:#6c757d;color:#6c757d;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-secondary .pace .pace-activity{box-shadow:inset 0 0 0 2px #6c757d,inset 0 0 0 7px #fff}.pace-mac-osx-secondary .pace .pace-progress{background-color:#6c757d;box-shadow:inset -1px 0 #6c757d,inset 0 -1px #6c757d,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-secondary .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-secondary .pace-progress{color:#6c757d}.pace-success .pace .pace-progress{background:#28a745}.pace-barber-shop-success .pace{background:#fff}.pace-barber-shop-success .pace .pace-progress{background:#28a745}.pace-barber-shop-success .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-success .pace .pace-progress:after{color:rgba(40,167,69,.2)}.pace-bounce-success .pace .pace-activity{background:#28a745}.pace-center-atom-success .pace-progress{height:100px;width:80px}.pace-center-atom-success .pace-progress:before{background:#28a745;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-success .pace-activity,.pace-center-atom-success .pace-activity:after,.pace-center-atom-success .pace-activity:before{border-color:#28a745}.pace-center-circle-success .pace .pace-progress{background:rgba(40,167,69,.8);color:#fff}.pace-center-radar-success .pace .pace-activity,.pace-center-radar-success .pace .pace-activity:before{border-color:#28a745 transparent transparent}.pace-center-simple-success .pace{background:#fff;border-color:#28a745}.pace-center-simple-success .pace .pace-progress{background:#28a745}.pace-material-success .pace{color:#28a745}.pace-corner-indicator-success .pace .pace-activity{background:#28a745}.pace-corner-indicator-success .pace .pace-activity:after,.pace-corner-indicator-success .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-success .pace .pace-activity:before{border-right-color:rgba(40,167,69,.2);border-left-color:rgba(40,167,69,.2)}.pace-corner-indicator-success .pace .pace-activity:after{border-top-color:rgba(40,167,69,.2);border-bottom-color:rgba(40,167,69,.2)}.pace-fill-left-success .pace .pace-progress{background-color:rgba(40,167,69,.2)}.pace-flash-success .pace .pace-progress{background:#28a745}.pace-flash-success .pace .pace-progress-inner{box-shadow:0 0 10px #28a745,0 0 5px #28a745}.pace-flash-success .pace .pace-activity{border-top-color:#28a745;border-left-color:#28a745}.pace-loading-bar-success .pace .pace-progress{background:#28a745;color:#28a745;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-success .pace .pace-activity{box-shadow:inset 0 0 0 2px #28a745,inset 0 0 0 7px #fff}.pace-mac-osx-success .pace .pace-progress{background-color:#28a745;box-shadow:inset -1px 0 #28a745,inset 0 -1px #28a745,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-success .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-success .pace-progress{color:#28a745}.pace-info .pace .pace-progress{background:#17a2b8}.pace-barber-shop-info .pace{background:#fff}.pace-barber-shop-info .pace .pace-progress{background:#17a2b8}.pace-barber-shop-info .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-info .pace .pace-progress:after{color:rgba(23,162,184,.2)}.pace-bounce-info .pace .pace-activity{background:#17a2b8}.pace-center-atom-info .pace-progress{height:100px;width:80px}.pace-center-atom-info .pace-progress:before{background:#17a2b8;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-info .pace-activity,.pace-center-atom-info .pace-activity:after,.pace-center-atom-info .pace-activity:before{border-color:#17a2b8}.pace-center-circle-info .pace .pace-progress{background:rgba(23,162,184,.8);color:#fff}.pace-center-radar-info .pace .pace-activity,.pace-center-radar-info .pace .pace-activity:before{border-color:#17a2b8 transparent transparent}.pace-center-simple-info .pace{background:#fff;border-color:#17a2b8}.pace-center-simple-info .pace .pace-progress{background:#17a2b8}.pace-material-info .pace{color:#17a2b8}.pace-corner-indicator-info .pace .pace-activity{background:#17a2b8}.pace-corner-indicator-info .pace .pace-activity:after,.pace-corner-indicator-info .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-info .pace .pace-activity:before{border-right-color:rgba(23,162,184,.2);border-left-color:rgba(23,162,184,.2)}.pace-corner-indicator-info .pace .pace-activity:after{border-top-color:rgba(23,162,184,.2);border-bottom-color:rgba(23,162,184,.2)}.pace-fill-left-info .pace .pace-progress{background-color:rgba(23,162,184,.2)}.pace-flash-info .pace .pace-progress{background:#17a2b8}.pace-flash-info .pace .pace-progress-inner{box-shadow:0 0 10px #17a2b8,0 0 5px #17a2b8}.pace-flash-info .pace .pace-activity{border-top-color:#17a2b8;border-left-color:#17a2b8}.pace-loading-bar-info .pace .pace-progress{background:#17a2b8;color:#17a2b8;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-info .pace .pace-activity{box-shadow:inset 0 0 0 2px #17a2b8,inset 0 0 0 7px #fff}.pace-mac-osx-info .pace .pace-progress{background-color:#17a2b8;box-shadow:inset -1px 0 #17a2b8,inset 0 -1px #17a2b8,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-info .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-info .pace-progress{color:#17a2b8}.pace-warning .pace .pace-progress{background:#ffc107}.pace-barber-shop-warning .pace{background:#1f2d3d}.pace-barber-shop-warning .pace .pace-progress{background:#ffc107}.pace-barber-shop-warning .pace .pace-activity{background-image:linear-gradient(45deg,rgba(31,45,61,.2) 25%,transparent 0,transparent 50%,rgba(31,45,61,.2) 0,rgba(31,45,61,.2) 75%,transparent 0,transparent)}.pace-big-counter-warning .pace .pace-progress:after{color:rgba(255,193,7,.2)}.pace-bounce-warning .pace .pace-activity{background:#ffc107}.pace-center-atom-warning .pace-progress{height:100px;width:80px}.pace-center-atom-warning .pace-progress:before{background:#ffc107;color:#1f2d3d;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-warning .pace-activity,.pace-center-atom-warning .pace-activity:after,.pace-center-atom-warning .pace-activity:before{border-color:#ffc107}.pace-center-circle-warning .pace .pace-progress{background:rgba(255,193,7,.8);color:#1f2d3d}.pace-center-radar-warning .pace .pace-activity,.pace-center-radar-warning .pace .pace-activity:before{border-color:#ffc107 transparent transparent}.pace-center-simple-warning .pace{background:#1f2d3d;border-color:#ffc107}.pace-center-simple-warning .pace .pace-progress{background:#ffc107}.pace-material-warning .pace{color:#ffc107}.pace-corner-indicator-warning .pace .pace-activity{background:#ffc107}.pace-corner-indicator-warning .pace .pace-activity:after,.pace-corner-indicator-warning .pace .pace-activity:before{border:5px solid #1f2d3d}.pace-corner-indicator-warning .pace .pace-activity:before{border-right-color:rgba(255,193,7,.2);border-left-color:rgba(255,193,7,.2)}.pace-corner-indicator-warning .pace .pace-activity:after{border-top-color:rgba(255,193,7,.2);border-bottom-color:rgba(255,193,7,.2)}.pace-fill-left-warning .pace .pace-progress{background-color:rgba(255,193,7,.2)}.pace-flash-warning .pace .pace-progress{background:#ffc107}.pace-flash-warning .pace .pace-progress-inner{box-shadow:0 0 10px #ffc107,0 0 5px #ffc107}.pace-flash-warning .pace .pace-activity{border-top-color:#ffc107;border-left-color:#ffc107}.pace-loading-bar-warning .pace .pace-progress{background:#ffc107;color:#ffc107;box-shadow:120px 0 #1f2d3d,240px 0 #1f2d3d}.pace-loading-bar-warning .pace .pace-activity{box-shadow:inset 0 0 0 2px #ffc107,inset 0 0 0 7px #1f2d3d}.pace-mac-osx-warning .pace .pace-progress{background-color:#ffc107;box-shadow:inset -1px 0 #ffc107,inset 0 -1px #ffc107,inset 0 2px rgba(31,45,61,.5),inset 0 6px rgba(31,45,61,.3)}.pace-mac-osx-warning .pace .pace-activity{background-image:radial-gradient(rgba(31,45,61,.65) 0,rgba(31,45,61,.15) 100%);height:12px}.pace-progress-color-warning .pace-progress{color:#ffc107}.pace-danger .pace .pace-progress{background:#dc3545}.pace-barber-shop-danger .pace{background:#fff}.pace-barber-shop-danger .pace .pace-progress{background:#dc3545}.pace-barber-shop-danger .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-danger .pace .pace-progress:after{color:rgba(220,53,69,.2)}.pace-bounce-danger .pace .pace-activity{background:#dc3545}.pace-center-atom-danger .pace-progress{height:100px;width:80px}.pace-center-atom-danger .pace-progress:before{background:#dc3545;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-danger .pace-activity,.pace-center-atom-danger .pace-activity:after,.pace-center-atom-danger .pace-activity:before{border-color:#dc3545}.pace-center-circle-danger .pace .pace-progress{background:rgba(220,53,69,.8);color:#fff}.pace-center-radar-danger .pace .pace-activity,.pace-center-radar-danger .pace .pace-activity:before{border-color:#dc3545 transparent transparent}.pace-center-simple-danger .pace{background:#fff;border-color:#dc3545}.pace-center-simple-danger .pace .pace-progress{background:#dc3545}.pace-material-danger .pace{color:#dc3545}.pace-corner-indicator-danger .pace .pace-activity{background:#dc3545}.pace-corner-indicator-danger .pace .pace-activity:after,.pace-corner-indicator-danger .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-danger .pace .pace-activity:before{border-right-color:rgba(220,53,69,.2);border-left-color:rgba(220,53,69,.2)}.pace-corner-indicator-danger .pace .pace-activity:after{border-top-color:rgba(220,53,69,.2);border-bottom-color:rgba(220,53,69,.2)}.pace-fill-left-danger .pace .pace-progress{background-color:rgba(220,53,69,.2)}.pace-flash-danger .pace .pace-progress{background:#dc3545}.pace-flash-danger .pace .pace-progress-inner{box-shadow:0 0 10px #dc3545,0 0 5px #dc3545}.pace-flash-danger .pace .pace-activity{border-top-color:#dc3545;border-left-color:#dc3545}.pace-loading-bar-danger .pace .pace-progress{background:#dc3545;color:#dc3545;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-danger .pace .pace-activity{box-shadow:inset 0 0 0 2px #dc3545,inset 0 0 0 7px #fff}.pace-mac-osx-danger .pace .pace-progress{background-color:#dc3545;box-shadow:inset -1px 0 #dc3545,inset 0 -1px #dc3545,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-danger .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-danger .pace-progress{color:#dc3545}.pace-light .pace .pace-progress{background:#f8f9fa}.pace-barber-shop-light .pace{background:#1f2d3d}.pace-barber-shop-light .pace .pace-progress{background:#f8f9fa}.pace-barber-shop-light .pace .pace-activity{background-image:linear-gradient(45deg,rgba(31,45,61,.2) 25%,transparent 0,transparent 50%,rgba(31,45,61,.2) 0,rgba(31,45,61,.2) 75%,transparent 0,transparent)}.pace-big-counter-light .pace .pace-progress:after{color:rgba(248,249,250,.2)}.pace-bounce-light .pace .pace-activity{background:#f8f9fa}.pace-center-atom-light .pace-progress{height:100px;width:80px}.pace-center-atom-light .pace-progress:before{background:#f8f9fa;color:#1f2d3d;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-light .pace-activity,.pace-center-atom-light .pace-activity:after,.pace-center-atom-light .pace-activity:before{border-color:#f8f9fa}.pace-center-circle-light .pace .pace-progress{background:rgba(248,249,250,.8);color:#1f2d3d}.pace-center-radar-light .pace .pace-activity,.pace-center-radar-light .pace .pace-activity:before{border-color:#f8f9fa transparent transparent}.pace-center-simple-light .pace{background:#1f2d3d;border-color:#f8f9fa}.pace-center-simple-light .pace .pace-progress{background:#f8f9fa}.pace-material-light .pace{color:#f8f9fa}.pace-corner-indicator-light .pace .pace-activity{background:#f8f9fa}.pace-corner-indicator-light .pace .pace-activity:after,.pace-corner-indicator-light .pace .pace-activity:before{border:5px solid #1f2d3d}.pace-corner-indicator-light .pace .pace-activity:before{border-right-color:rgba(248,249,250,.2);border-left-color:rgba(248,249,250,.2)}.pace-corner-indicator-light .pace .pace-activity:after{border-top-color:rgba(248,249,250,.2);border-bottom-color:rgba(248,249,250,.2)}.pace-fill-left-light .pace .pace-progress{background-color:rgba(248,249,250,.2)}.pace-flash-light .pace .pace-progress{background:#f8f9fa}.pace-flash-light .pace .pace-progress-inner{box-shadow:0 0 10px #f8f9fa,0 0 5px #f8f9fa}.pace-flash-light .pace .pace-activity{border-top-color:#f8f9fa;border-left-color:#f8f9fa}.pace-loading-bar-light .pace .pace-progress{background:#f8f9fa;color:#f8f9fa;box-shadow:120px 0 #1f2d3d,240px 0 #1f2d3d}.pace-loading-bar-light .pace .pace-activity{box-shadow:inset 0 0 0 2px #f8f9fa,inset 0 0 0 7px #1f2d3d}.pace-mac-osx-light .pace .pace-progress{background-color:#f8f9fa;box-shadow:inset -1px 0 #f8f9fa,inset 0 -1px #f8f9fa,inset 0 2px rgba(31,45,61,.5),inset 0 6px rgba(31,45,61,.3)}.pace-mac-osx-light .pace .pace-activity{background-image:radial-gradient(rgba(31,45,61,.65) 0,rgba(31,45,61,.15) 100%);height:12px}.pace-progress-color-light .pace-progress{color:#f8f9fa}.pace-dark .pace .pace-progress{background:#343a40}.pace-barber-shop-dark .pace{background:#fff}.pace-barber-shop-dark .pace .pace-progress{background:#343a40}.pace-barber-shop-dark .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-dark .pace .pace-progress:after{color:rgba(52,58,64,.2)}.pace-bounce-dark .pace .pace-activity{background:#343a40}.pace-center-atom-dark .pace-progress{height:100px;width:80px}.pace-center-atom-dark .pace-progress:before{background:#343a40;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-dark .pace-activity,.pace-center-atom-dark .pace-activity:after,.pace-center-atom-dark .pace-activity:before{border-color:#343a40}.pace-center-circle-dark .pace .pace-progress{background:rgba(52,58,64,.8);color:#fff}.pace-center-radar-dark .pace .pace-activity,.pace-center-radar-dark .pace .pace-activity:before{border-color:#343a40 transparent transparent}.pace-center-simple-dark .pace{background:#fff;border-color:#343a40}.pace-center-simple-dark .pace .pace-progress{background:#343a40}.pace-material-dark .pace{color:#343a40}.pace-corner-indicator-dark .pace .pace-activity{background:#343a40}.pace-corner-indicator-dark .pace .pace-activity:after,.pace-corner-indicator-dark .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-dark .pace .pace-activity:before{border-right-color:rgba(52,58,64,.2);border-left-color:rgba(52,58,64,.2)}.pace-corner-indicator-dark .pace .pace-activity:after{border-top-color:rgba(52,58,64,.2);border-bottom-color:rgba(52,58,64,.2)}.pace-fill-left-dark .pace .pace-progress{background-color:rgba(52,58,64,.2)}.pace-flash-dark .pace .pace-progress{background:#343a40}.pace-flash-dark .pace .pace-progress-inner{box-shadow:0 0 10px #343a40,0 0 5px #343a40}.pace-flash-dark .pace .pace-activity{border-top-color:#343a40;border-left-color:#343a40}.pace-loading-bar-dark .pace .pace-progress{background:#343a40;color:#343a40;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-dark .pace .pace-activity{box-shadow:inset 0 0 0 2px #343a40,inset 0 0 0 7px #fff}.pace-mac-osx-dark .pace .pace-progress{background-color:#343a40;box-shadow:inset -1px 0 #343a40,inset 0 -1px #343a40,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-dark .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-dark .pace-progress{color:#343a40}.pace-lightblue .pace .pace-progress{background:#3c8dbc}.pace-barber-shop-lightblue .pace{background:#fff}.pace-barber-shop-lightblue .pace .pace-progress{background:#3c8dbc}.pace-barber-shop-lightblue .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-lightblue .pace .pace-progress:after{color:rgba(60,141,188,.2)}.pace-bounce-lightblue .pace .pace-activity{background:#3c8dbc}.pace-center-atom-lightblue .pace-progress{height:100px;width:80px}.pace-center-atom-lightblue .pace-progress:before{background:#3c8dbc;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-lightblue .pace-activity,.pace-center-atom-lightblue .pace-activity:after,.pace-center-atom-lightblue .pace-activity:before{border-color:#3c8dbc}.pace-center-circle-lightblue .pace .pace-progress{background:rgba(60,141,188,.8);color:#fff}.pace-center-radar-lightblue .pace .pace-activity,.pace-center-radar-lightblue .pace .pace-activity:before{border-color:#3c8dbc transparent transparent}.pace-center-simple-lightblue .pace{background:#fff;border-color:#3c8dbc}.pace-center-simple-lightblue .pace .pace-progress{background:#3c8dbc}.pace-material-lightblue .pace{color:#3c8dbc}.pace-corner-indicator-lightblue .pace .pace-activity{background:#3c8dbc}.pace-corner-indicator-lightblue .pace .pace-activity:after,.pace-corner-indicator-lightblue .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-lightblue .pace .pace-activity:before{border-right-color:rgba(60,141,188,.2);border-left-color:rgba(60,141,188,.2)}.pace-corner-indicator-lightblue .pace .pace-activity:after{border-top-color:rgba(60,141,188,.2);border-bottom-color:rgba(60,141,188,.2)}.pace-fill-left-lightblue .pace .pace-progress{background-color:rgba(60,141,188,.2)}.pace-flash-lightblue .pace .pace-progress{background:#3c8dbc}.pace-flash-lightblue .pace .pace-progress-inner{box-shadow:0 0 10px #3c8dbc,0 0 5px #3c8dbc}.pace-flash-lightblue .pace .pace-activity{border-top-color:#3c8dbc;border-left-color:#3c8dbc}.pace-loading-bar-lightblue .pace .pace-progress{background:#3c8dbc;color:#3c8dbc;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-lightblue .pace .pace-activity{box-shadow:inset 0 0 0 2px #3c8dbc,inset 0 0 0 7px #fff}.pace-mac-osx-lightblue .pace .pace-progress{background-color:#3c8dbc;box-shadow:inset -1px 0 #3c8dbc,inset 0 -1px #3c8dbc,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-lightblue .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-lightblue .pace-progress{color:#3c8dbc}.pace-navy .pace .pace-progress{background:#001f3f}.pace-barber-shop-navy .pace{background:#fff}.pace-barber-shop-navy .pace .pace-progress{background:#001f3f}.pace-barber-shop-navy .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-navy .pace .pace-progress:after{color:rgba(0,31,63,.2)}.pace-bounce-navy .pace .pace-activity{background:#001f3f}.pace-center-atom-navy .pace-progress{height:100px;width:80px}.pace-center-atom-navy .pace-progress:before{background:#001f3f;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-navy .pace-activity,.pace-center-atom-navy .pace-activity:after,.pace-center-atom-navy .pace-activity:before{border-color:#001f3f}.pace-center-circle-navy .pace .pace-progress{background:rgba(0,31,63,.8);color:#fff}.pace-center-radar-navy .pace .pace-activity,.pace-center-radar-navy .pace .pace-activity:before{border-color:#001f3f transparent transparent}.pace-center-simple-navy .pace{background:#fff;border-color:#001f3f}.pace-center-simple-navy .pace .pace-progress{background:#001f3f}.pace-material-navy .pace{color:#001f3f}.pace-corner-indicator-navy .pace .pace-activity{background:#001f3f}.pace-corner-indicator-navy .pace .pace-activity:after,.pace-corner-indicator-navy .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-navy .pace .pace-activity:before{border-right-color:rgba(0,31,63,.2);border-left-color:rgba(0,31,63,.2)}.pace-corner-indicator-navy .pace .pace-activity:after{border-top-color:rgba(0,31,63,.2);border-bottom-color:rgba(0,31,63,.2)}.pace-fill-left-navy .pace .pace-progress{background-color:rgba(0,31,63,.2)}.pace-flash-navy .pace .pace-progress{background:#001f3f}.pace-flash-navy .pace .pace-progress-inner{box-shadow:0 0 10px #001f3f,0 0 5px #001f3f}.pace-flash-navy .pace .pace-activity{border-top-color:#001f3f;border-left-color:#001f3f}.pace-loading-bar-navy .pace .pace-progress{background:#001f3f;color:#001f3f;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-navy .pace .pace-activity{box-shadow:inset 0 0 0 2px #001f3f,inset 0 0 0 7px #fff}.pace-mac-osx-navy .pace .pace-progress{background-color:#001f3f;box-shadow:inset -1px 0 #001f3f,inset 0 -1px #001f3f,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-navy .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-navy .pace-progress{color:#001f3f}.pace-olive .pace .pace-progress{background:#3d9970}.pace-barber-shop-olive .pace{background:#fff}.pace-barber-shop-olive .pace .pace-progress{background:#3d9970}.pace-barber-shop-olive .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-olive .pace .pace-progress:after{color:rgba(61,153,112,.2)}.pace-bounce-olive .pace .pace-activity{background:#3d9970}.pace-center-atom-olive .pace-progress{height:100px;width:80px}.pace-center-atom-olive .pace-progress:before{background:#3d9970;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-olive .pace-activity,.pace-center-atom-olive .pace-activity:after,.pace-center-atom-olive .pace-activity:before{border-color:#3d9970}.pace-center-circle-olive .pace .pace-progress{background:rgba(61,153,112,.8);color:#fff}.pace-center-radar-olive .pace .pace-activity,.pace-center-radar-olive .pace .pace-activity:before{border-color:#3d9970 transparent transparent}.pace-center-simple-olive .pace{background:#fff;border-color:#3d9970}.pace-center-simple-olive .pace .pace-progress{background:#3d9970}.pace-material-olive .pace{color:#3d9970}.pace-corner-indicator-olive .pace .pace-activity{background:#3d9970}.pace-corner-indicator-olive .pace .pace-activity:after,.pace-corner-indicator-olive .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-olive .pace .pace-activity:before{border-right-color:rgba(61,153,112,.2);border-left-color:rgba(61,153,112,.2)}.pace-corner-indicator-olive .pace .pace-activity:after{border-top-color:rgba(61,153,112,.2);border-bottom-color:rgba(61,153,112,.2)}.pace-fill-left-olive .pace .pace-progress{background-color:rgba(61,153,112,.2)}.pace-flash-olive .pace .pace-progress{background:#3d9970}.pace-flash-olive .pace .pace-progress-inner{box-shadow:0 0 10px #3d9970,0 0 5px #3d9970}.pace-flash-olive .pace .pace-activity{border-top-color:#3d9970;border-left-color:#3d9970}.pace-loading-bar-olive .pace .pace-progress{background:#3d9970;color:#3d9970;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-olive .pace .pace-activity{box-shadow:inset 0 0 0 2px #3d9970,inset 0 0 0 7px #fff}.pace-mac-osx-olive .pace .pace-progress{background-color:#3d9970;box-shadow:inset -1px 0 #3d9970,inset 0 -1px #3d9970,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-olive .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-olive .pace-progress{color:#3d9970}.pace-lime .pace .pace-progress{background:#01ff70}.pace-barber-shop-lime .pace{background:#1f2d3d}.pace-barber-shop-lime .pace .pace-progress{background:#01ff70}.pace-barber-shop-lime .pace .pace-activity{background-image:linear-gradient(45deg,rgba(31,45,61,.2) 25%,transparent 0,transparent 50%,rgba(31,45,61,.2) 0,rgba(31,45,61,.2) 75%,transparent 0,transparent)}.pace-big-counter-lime .pace .pace-progress:after{color:rgba(1,255,112,.2)}.pace-bounce-lime .pace .pace-activity{background:#01ff70}.pace-center-atom-lime .pace-progress{height:100px;width:80px}.pace-center-atom-lime .pace-progress:before{background:#01ff70;color:#1f2d3d;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-lime .pace-activity,.pace-center-atom-lime .pace-activity:after,.pace-center-atom-lime .pace-activity:before{border-color:#01ff70}.pace-center-circle-lime .pace .pace-progress{background:rgba(1,255,112,.8);color:#1f2d3d}.pace-center-radar-lime .pace .pace-activity,.pace-center-radar-lime .pace .pace-activity:before{border-color:#01ff70 transparent transparent}.pace-center-simple-lime .pace{background:#1f2d3d;border-color:#01ff70}.pace-center-simple-lime .pace .pace-progress{background:#01ff70}.pace-material-lime .pace{color:#01ff70}.pace-corner-indicator-lime .pace .pace-activity{background:#01ff70}.pace-corner-indicator-lime .pace .pace-activity:after,.pace-corner-indicator-lime .pace .pace-activity:before{border:5px solid #1f2d3d}.pace-corner-indicator-lime .pace .pace-activity:before{border-right-color:rgba(1,255,112,.2);border-left-color:rgba(1,255,112,.2)}.pace-corner-indicator-lime .pace .pace-activity:after{border-top-color:rgba(1,255,112,.2);border-bottom-color:rgba(1,255,112,.2)}.pace-fill-left-lime .pace .pace-progress{background-color:rgba(1,255,112,.2)}.pace-flash-lime .pace .pace-progress{background:#01ff70}.pace-flash-lime .pace .pace-progress-inner{box-shadow:0 0 10px #01ff70,0 0 5px #01ff70}.pace-flash-lime .pace .pace-activity{border-top-color:#01ff70;border-left-color:#01ff70}.pace-loading-bar-lime .pace .pace-progress{background:#01ff70;color:#01ff70;box-shadow:120px 0 #1f2d3d,240px 0 #1f2d3d}.pace-loading-bar-lime .pace .pace-activity{box-shadow:inset 0 0 0 2px #01ff70,inset 0 0 0 7px #1f2d3d}.pace-mac-osx-lime .pace .pace-progress{background-color:#01ff70;box-shadow:inset -1px 0 #01ff70,inset 0 -1px #01ff70,inset 0 2px rgba(31,45,61,.5),inset 0 6px rgba(31,45,61,.3)}.pace-mac-osx-lime .pace .pace-activity{background-image:radial-gradient(rgba(31,45,61,.65) 0,rgba(31,45,61,.15) 100%);height:12px}.pace-progress-color-lime .pace-progress{color:#01ff70}.pace-fuchsia .pace .pace-progress{background:#f012be}.pace-barber-shop-fuchsia .pace{background:#fff}.pace-barber-shop-fuchsia .pace .pace-progress{background:#f012be}.pace-barber-shop-fuchsia .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-fuchsia .pace .pace-progress:after{color:rgba(240,18,190,.2)}.pace-bounce-fuchsia .pace .pace-activity{background:#f012be}.pace-center-atom-fuchsia .pace-progress{height:100px;width:80px}.pace-center-atom-fuchsia .pace-progress:before{background:#f012be;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-fuchsia .pace-activity,.pace-center-atom-fuchsia .pace-activity:after,.pace-center-atom-fuchsia .pace-activity:before{border-color:#f012be}.pace-center-circle-fuchsia .pace .pace-progress{background:rgba(240,18,190,.8);color:#fff}.pace-center-radar-fuchsia .pace .pace-activity,.pace-center-radar-fuchsia .pace .pace-activity:before{border-color:#f012be transparent transparent}.pace-center-simple-fuchsia .pace{background:#fff;border-color:#f012be}.pace-center-simple-fuchsia .pace .pace-progress{background:#f012be}.pace-material-fuchsia .pace{color:#f012be}.pace-corner-indicator-fuchsia .pace .pace-activity{background:#f012be}.pace-corner-indicator-fuchsia .pace .pace-activity:after,.pace-corner-indicator-fuchsia .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-fuchsia .pace .pace-activity:before{border-right-color:rgba(240,18,190,.2);border-left-color:rgba(240,18,190,.2)}.pace-corner-indicator-fuchsia .pace .pace-activity:after{border-top-color:rgba(240,18,190,.2);border-bottom-color:rgba(240,18,190,.2)}.pace-fill-left-fuchsia .pace .pace-progress{background-color:rgba(240,18,190,.2)}.pace-flash-fuchsia .pace .pace-progress{background:#f012be}.pace-flash-fuchsia .pace .pace-progress-inner{box-shadow:0 0 10px #f012be,0 0 5px #f012be}.pace-flash-fuchsia .pace .pace-activity{border-top-color:#f012be;border-left-color:#f012be}.pace-loading-bar-fuchsia .pace .pace-progress{background:#f012be;color:#f012be;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-fuchsia .pace .pace-activity{box-shadow:inset 0 0 0 2px #f012be,inset 0 0 0 7px #fff}.pace-mac-osx-fuchsia .pace .pace-progress{background-color:#f012be;box-shadow:inset -1px 0 #f012be,inset 0 -1px #f012be,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-fuchsia .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-fuchsia .pace-progress{color:#f012be}.pace-maroon .pace .pace-progress{background:#d81b60}.pace-barber-shop-maroon .pace{background:#fff}.pace-barber-shop-maroon .pace .pace-progress{background:#d81b60}.pace-barber-shop-maroon .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-maroon .pace .pace-progress:after{color:rgba(216,27,96,.2)}.pace-bounce-maroon .pace .pace-activity{background:#d81b60}.pace-center-atom-maroon .pace-progress{height:100px;width:80px}.pace-center-atom-maroon .pace-progress:before{background:#d81b60;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-maroon .pace-activity,.pace-center-atom-maroon .pace-activity:after,.pace-center-atom-maroon .pace-activity:before{border-color:#d81b60}.pace-center-circle-maroon .pace .pace-progress{background:rgba(216,27,96,.8);color:#fff}.pace-center-radar-maroon .pace .pace-activity,.pace-center-radar-maroon .pace .pace-activity:before{border-color:#d81b60 transparent transparent}.pace-center-simple-maroon .pace{background:#fff;border-color:#d81b60}.pace-center-simple-maroon .pace .pace-progress{background:#d81b60}.pace-material-maroon .pace{color:#d81b60}.pace-corner-indicator-maroon .pace .pace-activity{background:#d81b60}.pace-corner-indicator-maroon .pace .pace-activity:after,.pace-corner-indicator-maroon .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-maroon .pace .pace-activity:before{border-right-color:rgba(216,27,96,.2);border-left-color:rgba(216,27,96,.2)}.pace-corner-indicator-maroon .pace .pace-activity:after{border-top-color:rgba(216,27,96,.2);border-bottom-color:rgba(216,27,96,.2)}.pace-fill-left-maroon .pace .pace-progress{background-color:rgba(216,27,96,.2)}.pace-flash-maroon .pace .pace-progress{background:#d81b60}.pace-flash-maroon .pace .pace-progress-inner{box-shadow:0 0 10px #d81b60,0 0 5px #d81b60}.pace-flash-maroon .pace .pace-activity{border-top-color:#d81b60;border-left-color:#d81b60}.pace-loading-bar-maroon .pace .pace-progress{background:#d81b60;color:#d81b60;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-maroon .pace .pace-activity{box-shadow:inset 0 0 0 2px #d81b60,inset 0 0 0 7px #fff}.pace-mac-osx-maroon .pace .pace-progress{background-color:#d81b60;box-shadow:inset -1px 0 #d81b60,inset 0 -1px #d81b60,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-maroon .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-maroon .pace-progress{color:#d81b60}.pace-blue .pace .pace-progress{background:#007bff}.pace-barber-shop-blue .pace{background:#fff}.pace-barber-shop-blue .pace .pace-progress{background:#007bff}.pace-barber-shop-blue .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-blue .pace .pace-progress:after{color:rgba(0,123,255,.2)}.pace-bounce-blue .pace .pace-activity{background:#007bff}.pace-center-atom-blue .pace-progress{height:100px;width:80px}.pace-center-atom-blue .pace-progress:before{background:#007bff;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-blue .pace-activity,.pace-center-atom-blue .pace-activity:after,.pace-center-atom-blue .pace-activity:before{border-color:#007bff}.pace-center-circle-blue .pace .pace-progress{background:rgba(0,123,255,.8);color:#fff}.pace-center-radar-blue .pace .pace-activity,.pace-center-radar-blue .pace .pace-activity:before{border-color:#007bff transparent transparent}.pace-center-simple-blue .pace{background:#fff;border-color:#007bff}.pace-center-simple-blue .pace .pace-progress{background:#007bff}.pace-material-blue .pace{color:#007bff}.pace-corner-indicator-blue .pace .pace-activity{background:#007bff}.pace-corner-indicator-blue .pace .pace-activity:after,.pace-corner-indicator-blue .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-blue .pace .pace-activity:before{border-right-color:rgba(0,123,255,.2);border-left-color:rgba(0,123,255,.2)}.pace-corner-indicator-blue .pace .pace-activity:after{border-top-color:rgba(0,123,255,.2);border-bottom-color:rgba(0,123,255,.2)}.pace-fill-left-blue .pace .pace-progress{background-color:rgba(0,123,255,.2)}.pace-flash-blue .pace .pace-progress{background:#007bff}.pace-flash-blue .pace .pace-progress-inner{box-shadow:0 0 10px #007bff,0 0 5px #007bff}.pace-flash-blue .pace .pace-activity{border-top-color:#007bff;border-left-color:#007bff}.pace-loading-bar-blue .pace .pace-progress{background:#007bff;color:#007bff;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-blue .pace .pace-activity{box-shadow:inset 0 0 0 2px #007bff,inset 0 0 0 7px #fff}.pace-mac-osx-blue .pace .pace-progress{background-color:#007bff;box-shadow:inset -1px 0 #007bff,inset 0 -1px #007bff,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-blue .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-blue .pace-progress{color:#007bff}.pace-indigo .pace .pace-progress{background:#6610f2}.pace-barber-shop-indigo .pace{background:#fff}.pace-barber-shop-indigo .pace .pace-progress{background:#6610f2}.pace-barber-shop-indigo .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-indigo .pace .pace-progress:after{color:rgba(102,16,242,.2)}.pace-bounce-indigo .pace .pace-activity{background:#6610f2}.pace-center-atom-indigo .pace-progress{height:100px;width:80px}.pace-center-atom-indigo .pace-progress:before{background:#6610f2;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-indigo .pace-activity,.pace-center-atom-indigo .pace-activity:after,.pace-center-atom-indigo .pace-activity:before{border-color:#6610f2}.pace-center-circle-indigo .pace .pace-progress{background:rgba(102,16,242,.8);color:#fff}.pace-center-radar-indigo .pace .pace-activity,.pace-center-radar-indigo .pace .pace-activity:before{border-color:#6610f2 transparent transparent}.pace-center-simple-indigo .pace{background:#fff;border-color:#6610f2}.pace-center-simple-indigo .pace .pace-progress{background:#6610f2}.pace-material-indigo .pace{color:#6610f2}.pace-corner-indicator-indigo .pace .pace-activity{background:#6610f2}.pace-corner-indicator-indigo .pace .pace-activity:after,.pace-corner-indicator-indigo .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-indigo .pace .pace-activity:before{border-right-color:rgba(102,16,242,.2);border-left-color:rgba(102,16,242,.2)}.pace-corner-indicator-indigo .pace .pace-activity:after{border-top-color:rgba(102,16,242,.2);border-bottom-color:rgba(102,16,242,.2)}.pace-fill-left-indigo .pace .pace-progress{background-color:rgba(102,16,242,.2)}.pace-flash-indigo .pace .pace-progress{background:#6610f2}.pace-flash-indigo .pace .pace-progress-inner{box-shadow:0 0 10px #6610f2,0 0 5px #6610f2}.pace-flash-indigo .pace .pace-activity{border-top-color:#6610f2;border-left-color:#6610f2}.pace-loading-bar-indigo .pace .pace-progress{background:#6610f2;color:#6610f2;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-indigo .pace .pace-activity{box-shadow:inset 0 0 0 2px #6610f2,inset 0 0 0 7px #fff}.pace-mac-osx-indigo .pace .pace-progress{background-color:#6610f2;box-shadow:inset -1px 0 #6610f2,inset 0 -1px #6610f2,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-indigo .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-indigo .pace-progress{color:#6610f2}.pace-purple .pace .pace-progress{background:#6f42c1}.pace-barber-shop-purple .pace{background:#fff}.pace-barber-shop-purple .pace .pace-progress{background:#6f42c1}.pace-barber-shop-purple .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-purple .pace .pace-progress:after{color:rgba(111,66,193,.2)}.pace-bounce-purple .pace .pace-activity{background:#6f42c1}.pace-center-atom-purple .pace-progress{height:100px;width:80px}.pace-center-atom-purple .pace-progress:before{background:#6f42c1;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-purple .pace-activity,.pace-center-atom-purple .pace-activity:after,.pace-center-atom-purple .pace-activity:before{border-color:#6f42c1}.pace-center-circle-purple .pace .pace-progress{background:rgba(111,66,193,.8);color:#fff}.pace-center-radar-purple .pace .pace-activity,.pace-center-radar-purple .pace .pace-activity:before{border-color:#6f42c1 transparent transparent}.pace-center-simple-purple .pace{background:#fff;border-color:#6f42c1}.pace-center-simple-purple .pace .pace-progress{background:#6f42c1}.pace-material-purple .pace{color:#6f42c1}.pace-corner-indicator-purple .pace .pace-activity{background:#6f42c1}.pace-corner-indicator-purple .pace .pace-activity:after,.pace-corner-indicator-purple .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-purple .pace .pace-activity:before{border-right-color:rgba(111,66,193,.2);border-left-color:rgba(111,66,193,.2)}.pace-corner-indicator-purple .pace .pace-activity:after{border-top-color:rgba(111,66,193,.2);border-bottom-color:rgba(111,66,193,.2)}.pace-fill-left-purple .pace .pace-progress{background-color:rgba(111,66,193,.2)}.pace-flash-purple .pace .pace-progress{background:#6f42c1}.pace-flash-purple .pace .pace-progress-inner{box-shadow:0 0 10px #6f42c1,0 0 5px #6f42c1}.pace-flash-purple .pace .pace-activity{border-top-color:#6f42c1;border-left-color:#6f42c1}.pace-loading-bar-purple .pace .pace-progress{background:#6f42c1;color:#6f42c1;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-purple .pace .pace-activity{box-shadow:inset 0 0 0 2px #6f42c1,inset 0 0 0 7px #fff}.pace-mac-osx-purple .pace .pace-progress{background-color:#6f42c1;box-shadow:inset -1px 0 #6f42c1,inset 0 -1px #6f42c1,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-purple .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-purple .pace-progress{color:#6f42c1}.pace-pink .pace .pace-progress{background:#e83e8c}.pace-barber-shop-pink .pace{background:#fff}.pace-barber-shop-pink .pace .pace-progress{background:#e83e8c}.pace-barber-shop-pink .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-pink .pace .pace-progress:after{color:rgba(232,62,140,.2)}.pace-bounce-pink .pace .pace-activity{background:#e83e8c}.pace-center-atom-pink .pace-progress{height:100px;width:80px}.pace-center-atom-pink .pace-progress:before{background:#e83e8c;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-pink .pace-activity,.pace-center-atom-pink .pace-activity:after,.pace-center-atom-pink .pace-activity:before{border-color:#e83e8c}.pace-center-circle-pink .pace .pace-progress{background:rgba(232,62,140,.8);color:#fff}.pace-center-radar-pink .pace .pace-activity,.pace-center-radar-pink .pace .pace-activity:before{border-color:#e83e8c transparent transparent}.pace-center-simple-pink .pace{background:#fff;border-color:#e83e8c}.pace-center-simple-pink .pace .pace-progress{background:#e83e8c}.pace-material-pink .pace{color:#e83e8c}.pace-corner-indicator-pink .pace .pace-activity{background:#e83e8c}.pace-corner-indicator-pink .pace .pace-activity:after,.pace-corner-indicator-pink .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-pink .pace .pace-activity:before{border-right-color:rgba(232,62,140,.2);border-left-color:rgba(232,62,140,.2)}.pace-corner-indicator-pink .pace .pace-activity:after{border-top-color:rgba(232,62,140,.2);border-bottom-color:rgba(232,62,140,.2)}.pace-fill-left-pink .pace .pace-progress{background-color:rgba(232,62,140,.2)}.pace-flash-pink .pace .pace-progress{background:#e83e8c}.pace-flash-pink .pace .pace-progress-inner{box-shadow:0 0 10px #e83e8c,0 0 5px #e83e8c}.pace-flash-pink .pace .pace-activity{border-top-color:#e83e8c;border-left-color:#e83e8c}.pace-loading-bar-pink .pace .pace-progress{background:#e83e8c;color:#e83e8c;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-pink .pace .pace-activity{box-shadow:inset 0 0 0 2px #e83e8c,inset 0 0 0 7px #fff}.pace-mac-osx-pink .pace .pace-progress{background-color:#e83e8c;box-shadow:inset -1px 0 #e83e8c,inset 0 -1px #e83e8c,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-pink .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-pink .pace-progress{color:#e83e8c}.pace-red .pace .pace-progress{background:#dc3545}.pace-barber-shop-red .pace{background:#fff}.pace-barber-shop-red .pace .pace-progress{background:#dc3545}.pace-barber-shop-red .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-red .pace .pace-progress:after{color:rgba(220,53,69,.2)}.pace-bounce-red .pace .pace-activity{background:#dc3545}.pace-center-atom-red .pace-progress{height:100px;width:80px}.pace-center-atom-red .pace-progress:before{background:#dc3545;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-red .pace-activity,.pace-center-atom-red .pace-activity:after,.pace-center-atom-red .pace-activity:before{border-color:#dc3545}.pace-center-circle-red .pace .pace-progress{background:rgba(220,53,69,.8);color:#fff}.pace-center-radar-red .pace .pace-activity,.pace-center-radar-red .pace .pace-activity:before{border-color:#dc3545 transparent transparent}.pace-center-simple-red .pace{background:#fff;border-color:#dc3545}.pace-center-simple-red .pace .pace-progress{background:#dc3545}.pace-material-red .pace{color:#dc3545}.pace-corner-indicator-red .pace .pace-activity{background:#dc3545}.pace-corner-indicator-red .pace .pace-activity:after,.pace-corner-indicator-red .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-red .pace .pace-activity:before{border-right-color:rgba(220,53,69,.2);border-left-color:rgba(220,53,69,.2)}.pace-corner-indicator-red .pace .pace-activity:after{border-top-color:rgba(220,53,69,.2);border-bottom-color:rgba(220,53,69,.2)}.pace-fill-left-red .pace .pace-progress{background-color:rgba(220,53,69,.2)}.pace-flash-red .pace .pace-progress{background:#dc3545}.pace-flash-red .pace .pace-progress-inner{box-shadow:0 0 10px #dc3545,0 0 5px #dc3545}.pace-flash-red .pace .pace-activity{border-top-color:#dc3545;border-left-color:#dc3545}.pace-loading-bar-red .pace .pace-progress{background:#dc3545;color:#dc3545;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-red .pace .pace-activity{box-shadow:inset 0 0 0 2px #dc3545,inset 0 0 0 7px #fff}.pace-mac-osx-red .pace .pace-progress{background-color:#dc3545;box-shadow:inset -1px 0 #dc3545,inset 0 -1px #dc3545,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-red .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-red .pace-progress{color:#dc3545}.pace-orange .pace .pace-progress{background:#fd7e14}.pace-barber-shop-orange .pace{background:#1f2d3d}.pace-barber-shop-orange .pace .pace-progress{background:#fd7e14}.pace-barber-shop-orange .pace .pace-activity{background-image:linear-gradient(45deg,rgba(31,45,61,.2) 25%,transparent 0,transparent 50%,rgba(31,45,61,.2) 0,rgba(31,45,61,.2) 75%,transparent 0,transparent)}.pace-big-counter-orange .pace .pace-progress:after{color:rgba(253,126,20,.2)}.pace-bounce-orange .pace .pace-activity{background:#fd7e14}.pace-center-atom-orange .pace-progress{height:100px;width:80px}.pace-center-atom-orange .pace-progress:before{background:#fd7e14;color:#1f2d3d;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-orange .pace-activity,.pace-center-atom-orange .pace-activity:after,.pace-center-atom-orange .pace-activity:before{border-color:#fd7e14}.pace-center-circle-orange .pace .pace-progress{background:rgba(253,126,20,.8);color:#1f2d3d}.pace-center-radar-orange .pace .pace-activity,.pace-center-radar-orange .pace .pace-activity:before{border-color:#fd7e14 transparent transparent}.pace-center-simple-orange .pace{background:#1f2d3d;border-color:#fd7e14}.pace-center-simple-orange .pace .pace-progress{background:#fd7e14}.pace-material-orange .pace{color:#fd7e14}.pace-corner-indicator-orange .pace .pace-activity{background:#fd7e14}.pace-corner-indicator-orange .pace .pace-activity:after,.pace-corner-indicator-orange .pace .pace-activity:before{border:5px solid #1f2d3d}.pace-corner-indicator-orange .pace .pace-activity:before{border-right-color:rgba(253,126,20,.2);border-left-color:rgba(253,126,20,.2)}.pace-corner-indicator-orange .pace .pace-activity:after{border-top-color:rgba(253,126,20,.2);border-bottom-color:rgba(253,126,20,.2)}.pace-fill-left-orange .pace .pace-progress{background-color:rgba(253,126,20,.2)}.pace-flash-orange .pace .pace-progress{background:#fd7e14}.pace-flash-orange .pace .pace-progress-inner{box-shadow:0 0 10px #fd7e14,0 0 5px #fd7e14}.pace-flash-orange .pace .pace-activity{border-top-color:#fd7e14;border-left-color:#fd7e14}.pace-loading-bar-orange .pace .pace-progress{background:#fd7e14;color:#fd7e14;box-shadow:120px 0 #1f2d3d,240px 0 #1f2d3d}.pace-loading-bar-orange .pace .pace-activity{box-shadow:inset 0 0 0 2px #fd7e14,inset 0 0 0 7px #1f2d3d}.pace-mac-osx-orange .pace .pace-progress{background-color:#fd7e14;box-shadow:inset -1px 0 #fd7e14,inset 0 -1px #fd7e14,inset 0 2px rgba(31,45,61,.5),inset 0 6px rgba(31,45,61,.3)}.pace-mac-osx-orange .pace .pace-activity{background-image:radial-gradient(rgba(31,45,61,.65) 0,rgba(31,45,61,.15) 100%);height:12px}.pace-progress-color-orange .pace-progress{color:#fd7e14}.pace-yellow .pace .pace-progress{background:#ffc107}.pace-barber-shop-yellow .pace{background:#1f2d3d}.pace-barber-shop-yellow .pace .pace-progress{background:#ffc107}.pace-barber-shop-yellow .pace .pace-activity{background-image:linear-gradient(45deg,rgba(31,45,61,.2) 25%,transparent 0,transparent 50%,rgba(31,45,61,.2) 0,rgba(31,45,61,.2) 75%,transparent 0,transparent)}.pace-big-counter-yellow .pace .pace-progress:after{color:rgba(255,193,7,.2)}.pace-bounce-yellow .pace .pace-activity{background:#ffc107}.pace-center-atom-yellow .pace-progress{height:100px;width:80px}.pace-center-atom-yellow .pace-progress:before{background:#ffc107;color:#1f2d3d;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-yellow .pace-activity,.pace-center-atom-yellow .pace-activity:after,.pace-center-atom-yellow .pace-activity:before{border-color:#ffc107}.pace-center-circle-yellow .pace .pace-progress{background:rgba(255,193,7,.8);color:#1f2d3d}.pace-center-radar-yellow .pace .pace-activity,.pace-center-radar-yellow .pace .pace-activity:before{border-color:#ffc107 transparent transparent}.pace-center-simple-yellow .pace{background:#1f2d3d;border-color:#ffc107}.pace-center-simple-yellow .pace .pace-progress{background:#ffc107}.pace-material-yellow .pace{color:#ffc107}.pace-corner-indicator-yellow .pace .pace-activity{background:#ffc107}.pace-corner-indicator-yellow .pace .pace-activity:after,.pace-corner-indicator-yellow .pace .pace-activity:before{border:5px solid #1f2d3d}.pace-corner-indicator-yellow .pace .pace-activity:before{border-right-color:rgba(255,193,7,.2);border-left-color:rgba(255,193,7,.2)}.pace-corner-indicator-yellow .pace .pace-activity:after{border-top-color:rgba(255,193,7,.2);border-bottom-color:rgba(255,193,7,.2)}.pace-fill-left-yellow .pace .pace-progress{background-color:rgba(255,193,7,.2)}.pace-flash-yellow .pace .pace-progress{background:#ffc107}.pace-flash-yellow .pace .pace-progress-inner{box-shadow:0 0 10px #ffc107,0 0 5px #ffc107}.pace-flash-yellow .pace .pace-activity{border-top-color:#ffc107;border-left-color:#ffc107}.pace-loading-bar-yellow .pace .pace-progress{background:#ffc107;color:#ffc107;box-shadow:120px 0 #1f2d3d,240px 0 #1f2d3d}.pace-loading-bar-yellow .pace .pace-activity{box-shadow:inset 0 0 0 2px #ffc107,inset 0 0 0 7px #1f2d3d}.pace-mac-osx-yellow .pace .pace-progress{background-color:#ffc107;box-shadow:inset -1px 0 #ffc107,inset 0 -1px #ffc107,inset 0 2px rgba(31,45,61,.5),inset 0 6px rgba(31,45,61,.3)}.pace-mac-osx-yellow .pace .pace-activity{background-image:radial-gradient(rgba(31,45,61,.65) 0,rgba(31,45,61,.15) 100%);height:12px}.pace-progress-color-yellow .pace-progress{color:#ffc107}.pace-green .pace .pace-progress{background:#28a745}.pace-barber-shop-green .pace{background:#fff}.pace-barber-shop-green .pace .pace-progress{background:#28a745}.pace-barber-shop-green .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-green .pace .pace-progress:after{color:rgba(40,167,69,.2)}.pace-bounce-green .pace .pace-activity{background:#28a745}.pace-center-atom-green .pace-progress{height:100px;width:80px}.pace-center-atom-green .pace-progress:before{background:#28a745;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-green .pace-activity,.pace-center-atom-green .pace-activity:after,.pace-center-atom-green .pace-activity:before{border-color:#28a745}.pace-center-circle-green .pace .pace-progress{background:rgba(40,167,69,.8);color:#fff}.pace-center-radar-green .pace .pace-activity,.pace-center-radar-green .pace .pace-activity:before{border-color:#28a745 transparent transparent}.pace-center-simple-green .pace{background:#fff;border-color:#28a745}.pace-center-simple-green .pace .pace-progress{background:#28a745}.pace-material-green .pace{color:#28a745}.pace-corner-indicator-green .pace .pace-activity{background:#28a745}.pace-corner-indicator-green .pace .pace-activity:after,.pace-corner-indicator-green .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-green .pace .pace-activity:before{border-right-color:rgba(40,167,69,.2);border-left-color:rgba(40,167,69,.2)}.pace-corner-indicator-green .pace .pace-activity:after{border-top-color:rgba(40,167,69,.2);border-bottom-color:rgba(40,167,69,.2)}.pace-fill-left-green .pace .pace-progress{background-color:rgba(40,167,69,.2)}.pace-flash-green .pace .pace-progress{background:#28a745}.pace-flash-green .pace .pace-progress-inner{box-shadow:0 0 10px #28a745,0 0 5px #28a745}.pace-flash-green .pace .pace-activity{border-top-color:#28a745;border-left-color:#28a745}.pace-loading-bar-green .pace .pace-progress{background:#28a745;color:#28a745;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-green .pace .pace-activity{box-shadow:inset 0 0 0 2px #28a745,inset 0 0 0 7px #fff}.pace-mac-osx-green .pace .pace-progress{background-color:#28a745;box-shadow:inset -1px 0 #28a745,inset 0 -1px #28a745,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-green .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-green .pace-progress{color:#28a745}.pace-teal .pace .pace-progress{background:#20c997}.pace-barber-shop-teal .pace{background:#fff}.pace-barber-shop-teal .pace .pace-progress{background:#20c997}.pace-barber-shop-teal .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-teal .pace .pace-progress:after{color:rgba(32,201,151,.2)}.pace-bounce-teal .pace .pace-activity{background:#20c997}.pace-center-atom-teal .pace-progress{height:100px;width:80px}.pace-center-atom-teal .pace-progress:before{background:#20c997;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-teal .pace-activity,.pace-center-atom-teal .pace-activity:after,.pace-center-atom-teal .pace-activity:before{border-color:#20c997}.pace-center-circle-teal .pace .pace-progress{background:rgba(32,201,151,.8);color:#fff}.pace-center-radar-teal .pace .pace-activity,.pace-center-radar-teal .pace .pace-activity:before{border-color:#20c997 transparent transparent}.pace-center-simple-teal .pace{background:#fff;border-color:#20c997}.pace-center-simple-teal .pace .pace-progress{background:#20c997}.pace-material-teal .pace{color:#20c997}.pace-corner-indicator-teal .pace .pace-activity{background:#20c997}.pace-corner-indicator-teal .pace .pace-activity:after,.pace-corner-indicator-teal .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-teal .pace .pace-activity:before{border-right-color:rgba(32,201,151,.2);border-left-color:rgba(32,201,151,.2)}.pace-corner-indicator-teal .pace .pace-activity:after{border-top-color:rgba(32,201,151,.2);border-bottom-color:rgba(32,201,151,.2)}.pace-fill-left-teal .pace .pace-progress{background-color:rgba(32,201,151,.2)}.pace-flash-teal .pace .pace-progress{background:#20c997}.pace-flash-teal .pace .pace-progress-inner{box-shadow:0 0 10px #20c997,0 0 5px #20c997}.pace-flash-teal .pace .pace-activity{border-top-color:#20c997;border-left-color:#20c997}.pace-loading-bar-teal .pace .pace-progress{background:#20c997;color:#20c997;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-teal .pace .pace-activity{box-shadow:inset 0 0 0 2px #20c997,inset 0 0 0 7px #fff}.pace-mac-osx-teal .pace .pace-progress{background-color:#20c997;box-shadow:inset -1px 0 #20c997,inset 0 -1px #20c997,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-teal .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-teal .pace-progress{color:#20c997}.pace-cyan .pace .pace-progress{background:#17a2b8}.pace-barber-shop-cyan .pace{background:#fff}.pace-barber-shop-cyan .pace .pace-progress{background:#17a2b8}.pace-barber-shop-cyan .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-cyan .pace .pace-progress:after{color:rgba(23,162,184,.2)}.pace-bounce-cyan .pace .pace-activity{background:#17a2b8}.pace-center-atom-cyan .pace-progress{height:100px;width:80px}.pace-center-atom-cyan .pace-progress:before{background:#17a2b8;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-cyan .pace-activity,.pace-center-atom-cyan .pace-activity:after,.pace-center-atom-cyan .pace-activity:before{border-color:#17a2b8}.pace-center-circle-cyan .pace .pace-progress{background:rgba(23,162,184,.8);color:#fff}.pace-center-radar-cyan .pace .pace-activity,.pace-center-radar-cyan .pace .pace-activity:before{border-color:#17a2b8 transparent transparent}.pace-center-simple-cyan .pace{background:#fff;border-color:#17a2b8}.pace-center-simple-cyan .pace .pace-progress{background:#17a2b8}.pace-material-cyan .pace{color:#17a2b8}.pace-corner-indicator-cyan .pace .pace-activity{background:#17a2b8}.pace-corner-indicator-cyan .pace .pace-activity:after,.pace-corner-indicator-cyan .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-cyan .pace .pace-activity:before{border-right-color:rgba(23,162,184,.2);border-left-color:rgba(23,162,184,.2)}.pace-corner-indicator-cyan .pace .pace-activity:after{border-top-color:rgba(23,162,184,.2);border-bottom-color:rgba(23,162,184,.2)}.pace-fill-left-cyan .pace .pace-progress{background-color:rgba(23,162,184,.2)}.pace-flash-cyan .pace .pace-progress{background:#17a2b8}.pace-flash-cyan .pace .pace-progress-inner{box-shadow:0 0 10px #17a2b8,0 0 5px #17a2b8}.pace-flash-cyan .pace .pace-activity{border-top-color:#17a2b8;border-left-color:#17a2b8}.pace-loading-bar-cyan .pace .pace-progress{background:#17a2b8;color:#17a2b8;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-cyan .pace .pace-activity{box-shadow:inset 0 0 0 2px #17a2b8,inset 0 0 0 7px #fff}.pace-mac-osx-cyan .pace .pace-progress{background-color:#17a2b8;box-shadow:inset -1px 0 #17a2b8,inset 0 -1px #17a2b8,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-cyan .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-cyan .pace-progress{color:#17a2b8}.pace-white .pace .pace-progress{background:#fff}.pace-barber-shop-white .pace{background:#1f2d3d}.pace-barber-shop-white .pace .pace-progress{background:#fff}.pace-barber-shop-white .pace .pace-activity{background-image:linear-gradient(45deg,rgba(31,45,61,.2) 25%,transparent 0,transparent 50%,rgba(31,45,61,.2) 0,rgba(31,45,61,.2) 75%,transparent 0,transparent)}.pace-big-counter-white .pace .pace-progress:after{color:hsla(0,0%,100%,.2)}.pace-bounce-white .pace .pace-activity{background:#fff}.pace-center-atom-white .pace-progress{height:100px;width:80px}.pace-center-atom-white .pace-progress:before{background:#fff;color:#1f2d3d;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-white .pace-activity,.pace-center-atom-white .pace-activity:after,.pace-center-atom-white .pace-activity:before{border-color:#fff}.pace-center-circle-white .pace .pace-progress{background:hsla(0,0%,100%,.8);color:#1f2d3d}.pace-center-radar-white .pace .pace-activity,.pace-center-radar-white .pace .pace-activity:before{border-color:#fff transparent transparent}.pace-center-simple-white .pace{background:#1f2d3d;border-color:#fff}.pace-center-simple-white .pace .pace-progress{background:#fff}.pace-material-white .pace{color:#fff}.pace-corner-indicator-white .pace .pace-activity{background:#fff}.pace-corner-indicator-white .pace .pace-activity:after,.pace-corner-indicator-white .pace .pace-activity:before{border:5px solid #1f2d3d}.pace-corner-indicator-white .pace .pace-activity:before{border-right-color:hsla(0,0%,100%,.2);border-left-color:hsla(0,0%,100%,.2)}.pace-corner-indicator-white .pace .pace-activity:after{border-top-color:hsla(0,0%,100%,.2);border-bottom-color:hsla(0,0%,100%,.2)}.pace-fill-left-white .pace .pace-progress{background-color:hsla(0,0%,100%,.2)}.pace-flash-white .pace .pace-progress{background:#fff}.pace-flash-white .pace .pace-progress-inner{box-shadow:0 0 10px #fff,0 0 5px #fff}.pace-flash-white .pace .pace-activity{border-top-color:#fff;border-left-color:#fff}.pace-loading-bar-white .pace .pace-progress{background:#fff;color:#fff;box-shadow:120px 0 #1f2d3d,240px 0 #1f2d3d}.pace-loading-bar-white .pace .pace-activity{box-shadow:inset 0 0 0 2px #fff,inset 0 0 0 7px #1f2d3d}.pace-mac-osx-white .pace .pace-progress{background-color:#fff;box-shadow:inset -1px 0 #fff,inset 0 -1px #fff,inset 0 2px rgba(31,45,61,.5),inset 0 6px rgba(31,45,61,.3)}.pace-mac-osx-white .pace .pace-activity{background-image:radial-gradient(rgba(31,45,61,.65) 0,rgba(31,45,61,.15) 100%);height:12px}.pace-progress-color-white .pace-progress{color:#fff}.pace-gray .pace .pace-progress{background:#6c757d}.pace-barber-shop-gray .pace{background:#fff}.pace-barber-shop-gray .pace .pace-progress{background:#6c757d}.pace-barber-shop-gray .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-gray .pace .pace-progress:after{color:rgba(108,117,125,.2)}.pace-bounce-gray .pace .pace-activity{background:#6c757d}.pace-center-atom-gray .pace-progress{height:100px;width:80px}.pace-center-atom-gray .pace-progress:before{background:#6c757d;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-gray .pace-activity,.pace-center-atom-gray .pace-activity:after,.pace-center-atom-gray .pace-activity:before{border-color:#6c757d}.pace-center-circle-gray .pace .pace-progress{background:rgba(108,117,125,.8);color:#fff}.pace-center-radar-gray .pace .pace-activity,.pace-center-radar-gray .pace .pace-activity:before{border-color:#6c757d transparent transparent}.pace-center-simple-gray .pace{background:#fff;border-color:#6c757d}.pace-center-simple-gray .pace .pace-progress{background:#6c757d}.pace-material-gray .pace{color:#6c757d}.pace-corner-indicator-gray .pace .pace-activity{background:#6c757d}.pace-corner-indicator-gray .pace .pace-activity:after,.pace-corner-indicator-gray .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-gray .pace .pace-activity:before{border-right-color:rgba(108,117,125,.2);border-left-color:rgba(108,117,125,.2)}.pace-corner-indicator-gray .pace .pace-activity:after{border-top-color:rgba(108,117,125,.2);border-bottom-color:rgba(108,117,125,.2)}.pace-fill-left-gray .pace .pace-progress{background-color:rgba(108,117,125,.2)}.pace-flash-gray .pace .pace-progress{background:#6c757d}.pace-flash-gray .pace .pace-progress-inner{box-shadow:0 0 10px #6c757d,0 0 5px #6c757d}.pace-flash-gray .pace .pace-activity{border-top-color:#6c757d;border-left-color:#6c757d}.pace-loading-bar-gray .pace .pace-progress{background:#6c757d;color:#6c757d;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-gray .pace .pace-activity{box-shadow:inset 0 0 0 2px #6c757d,inset 0 0 0 7px #fff}.pace-mac-osx-gray .pace .pace-progress{background-color:#6c757d;box-shadow:inset -1px 0 #6c757d,inset 0 -1px #6c757d,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-gray .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-gray .pace-progress{color:#6c757d}.pace-gray-dark .pace .pace-progress{background:#343a40}.pace-barber-shop-gray-dark .pace{background:#fff}.pace-barber-shop-gray-dark .pace .pace-progress{background:#343a40}.pace-barber-shop-gray-dark .pace .pace-activity{background-image:linear-gradient(45deg,hsla(0,0%,100%,.2) 25%,transparent 0,transparent 50%,hsla(0,0%,100%,.2) 0,hsla(0,0%,100%,.2) 75%,transparent 0,transparent)}.pace-big-counter-gray-dark .pace .pace-progress:after{color:rgba(52,58,64,.2)}.pace-bounce-gray-dark .pace .pace-activity{background:#343a40}.pace-center-atom-gray-dark .pace-progress{height:100px;width:80px}.pace-center-atom-gray-dark .pace-progress:before{background:#343a40;color:#fff;font-size:.8rem;line-height:.7rem;padding-top:17%}.pace-center-atom-gray-dark .pace-activity,.pace-center-atom-gray-dark .pace-activity:after,.pace-center-atom-gray-dark .pace-activity:before{border-color:#343a40}.pace-center-circle-gray-dark .pace .pace-progress{background:rgba(52,58,64,.8);color:#fff}.pace-center-radar-gray-dark .pace .pace-activity,.pace-center-radar-gray-dark .pace .pace-activity:before{border-color:#343a40 transparent transparent}.pace-center-simple-gray-dark .pace{background:#fff;border-color:#343a40}.pace-center-simple-gray-dark .pace .pace-progress{background:#343a40}.pace-material-gray-dark .pace{color:#343a40}.pace-corner-indicator-gray-dark .pace .pace-activity{background:#343a40}.pace-corner-indicator-gray-dark .pace .pace-activity:after,.pace-corner-indicator-gray-dark .pace .pace-activity:before{border:5px solid #fff}.pace-corner-indicator-gray-dark .pace .pace-activity:before{border-right-color:rgba(52,58,64,.2);border-left-color:rgba(52,58,64,.2)}.pace-corner-indicator-gray-dark .pace .pace-activity:after{border-top-color:rgba(52,58,64,.2);border-bottom-color:rgba(52,58,64,.2)}.pace-fill-left-gray-dark .pace .pace-progress{background-color:rgba(52,58,64,.2)}.pace-flash-gray-dark .pace .pace-progress{background:#343a40}.pace-flash-gray-dark .pace .pace-progress-inner{box-shadow:0 0 10px #343a40,0 0 5px #343a40}.pace-flash-gray-dark .pace .pace-activity{border-top-color:#343a40;border-left-color:#343a40}.pace-loading-bar-gray-dark .pace .pace-progress{background:#343a40;color:#343a40;box-shadow:120px 0 #fff,240px 0 #fff}.pace-loading-bar-gray-dark .pace .pace-activity{box-shadow:inset 0 0 0 2px #343a40,inset 0 0 0 7px #fff}.pace-mac-osx-gray-dark .pace .pace-progress{background-color:#343a40;box-shadow:inset -1px 0 #343a40,inset 0 -1px #343a40,inset 0 2px hsla(0,0%,100%,.5),inset 0 6px hsla(0,0%,100%,.3)}.pace-mac-osx-gray-dark .pace .pace-activity{background-image:radial-gradient(hsla(0,0%,100%,.65) 0,hsla(0,0%,100%,.15) 100%);height:12px}.pace-progress-color-gray-dark .pace-progress{color:#343a40}.bootstrap-switch{border:1px solid #ced4da;border-radius:.25rem;cursor:pointer;direction:ltr;display:inline-block;line-height:.5rem;overflow:hidden;position:relative;text-align:left;transition:border-color .15s ease-in-out,box-shadow .15s ease-in-out;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;vertical-align:middle;z-index:0}.bootstrap-switch .bootstrap-switch-container{border-radius:.25rem;display:inline-block;top:0;transform:translateZ(0)}.bootstrap-switch:focus-within{box-shadow:0 0 0 .2rem rgba(0,123,255,.25)}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on,.bootstrap-switch .bootstrap-switch-label{box-sizing:border-box;cursor:pointer;display:table-cell;font-size:1rem;font-weight:500;line-height:1.2rem;padding:.25rem .5rem;vertical-align:middle}.bootstrap-switch .bootstrap-switch-handle-off,.bootstrap-switch .bootstrap-switch-handle-on{text-align:center;z-index:1}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-default,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-default{background:#e9ecef;color:#1f2d3d}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-primary,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-primary{background:#007bff;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-secondary,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-secondary{background:#6c757d;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-success,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-success{background:#28a745;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-info,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-info{background:#17a2b8;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-warning,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-warning{background:#ffc107;color:#1f2d3d}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-danger,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-danger{background:#dc3545;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-light,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-light{background:#f8f9fa;color:#1f2d3d}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-dark,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-dark{background:#343a40;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-lightblue,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-lightblue{background:#3c8dbc;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-navy,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-navy{background:#001f3f;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-olive,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-olive{background:#3d9970;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-lime,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-lime{background:#01ff70;color:#1f2d3d}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-fuchsia,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-fuchsia{background:#f012be;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-maroon,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-maroon{background:#d81b60;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-blue,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-blue{background:#007bff;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-indigo,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-indigo{background:#6610f2;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-purple,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-purple{background:#6f42c1;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-pink,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-pink{background:#e83e8c;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-red,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-red{background:#dc3545;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-orange,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-orange{background:#fd7e14;color:#1f2d3d}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-yellow,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-yellow{background:#ffc107;color:#1f2d3d}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-green,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-green{background:#28a745;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-teal,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-teal{background:#20c997;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-cyan,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-cyan{background:#17a2b8;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-white,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-white{background:#fff;color:#1f2d3d}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-gray,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-gray{background:#6c757d;color:#fff}.bootstrap-switch .bootstrap-switch-handle-off.bootstrap-switch-gray-dark,.bootstrap-switch .bootstrap-switch-handle-on.bootstrap-switch-gray-dark{background:#343a40;color:#fff}.bootstrap-switch .bootstrap-switch-handle-on{border-bottom-left-radius:.1rem;border-top-left-radius:.1rem}.bootstrap-switch .bootstrap-switch-handle-off{border-bottom-right-radius:.1rem;border-top-right-radius:.1rem}.bootstrap-switch input[type=checkbox],.bootstrap-switch input[type=radio]{filter:alpha(opacity=0);left:0;margin:0;opacity:0;position:absolute;top:0;visibility:hidden;z-index:-1}.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-mini .bootstrap-switch-label{font-size:.875rem;line-height:1.5;padding:.1rem .3rem}.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-small .bootstrap-switch-label{font-size:.875rem;line-height:1.5;padding:.2rem .4rem}.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-large .bootstrap-switch-label{font-size:1.25rem;line-height:1.3333333rem;padding:.3rem .5rem}.bootstrap-switch.bootstrap-switch-disabled,.bootstrap-switch.bootstrap-switch-indeterminate,.bootstrap-switch.bootstrap-switch-readonly{cursor:default}.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-disabled .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-indeterminate .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-off,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-handle-on,.bootstrap-switch.bootstrap-switch-readonly .bootstrap-switch-label{cursor:default;filter:alpha(opacity=50);opacity:.5}.bootstrap-switch.bootstrap-switch-animate .bootstrap-switch-container{transition:margin-left .5s}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-on{border-radius:0 .1rem .1rem 0}.bootstrap-switch.bootstrap-switch-inverse .bootstrap-switch-handle-off{border-radius:.1rem 0 0 .1rem}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-off .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-on .bootstrap-switch-label{border-bottom-right-radius:.1rem;border-top-right-radius:.1rem}.bootstrap-switch.bootstrap-switch-inverse.bootstrap-switch-on .bootstrap-switch-label,.bootstrap-switch.bootstrap-switch-off .bootstrap-switch-label{border-bottom-left-radius:.1rem;border-top-left-radius:.1rem}.jqstooltip{height:auto!important;padding:5px!important;width:auto!important}.connectedSortable{min-height:100px}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.sort-highlight{background:#f8f9fa;border:1px dashed #dee2e6;margin-bottom:10px}.chart{overflow:hidden;position:relative}.border-transparent{border-color:transparent!important}.description-block{display:block;margin:10px 0;text-align:center}.description-block.margin-bottom{margin-bottom:25px}.description-block>.description-header{font-size:16px;font-weight:600;margin:0;padding:0}.description-block>.description-text{text-transform:uppercase}.description-block .description-icon{font-size:16px}.list-group-unbordered>.list-group-item{border-left:0;border-radius:0;border-right:0;padding-left:0;padding-right:0}.list-header{color:#6c757d;font-size:15px;font-weight:700;padding:10px 4px}.list-seperator{background:rgba(0,0,0,.125);height:1px;margin:15px 0 9px}.list-link>a{color:#6c757d;padding:4px}.list-link>a:hover{color:#212529}.user-block{float:left}.user-block img{float:left;height:40px;width:40px}.user-block .comment,.user-block .description,.user-block .username{display:block;margin-left:50px}.user-block .username{font-size:16px;font-weight:600;margin-top:-1px}.user-block .description{color:#6c757d;font-size:13px;margin-top:-3px}.user-block.user-block-sm img{width:1.875rem;height:1.875rem}.user-block.user-block-sm .comment,.user-block.user-block-sm .description,.user-block.user-block-sm .username{margin-left:40px}.user-block.user-block-sm .username{font-size:14px}.img-lg,.img-md,.img-sm{float:left}.img-sm{height:1.875rem;width:1.875rem}.img-sm+.img-push{margin-left:2.5rem}.img-md{width:3.75rem;height:3.75rem}.img-md+.img-push{margin-left:4.375rem}.img-lg{width:6.25rem;height:6.25rem}.img-lg+.img-push{margin-left:6.875rem}.img-bordered{border:3px solid #adb5bd;padding:3px}.img-bordered-sm{border:2px solid #adb5bd;padding:2px}.img-rounded{border-radius:.25rem}.img-circle{border-radius:50%}.img-size-32,.img-size-50,.img-size-64{height:auto}.img-size-64{width:64px}.img-size-50{width:50px}.img-size-32{width:32px}.size-32,.size-40,.size-50{display:block;text-align:center}.size-32{height:32px;line-height:32px;width:32px}.size-40{height:40px;line-height:40px;width:40px}.size-50{height:50px;line-height:50px;width:50px}.attachment-block{background:#f8f9fa;border:1px solid rgba(0,0,0,.125);margin-bottom:10px;padding:5px}.attachment-block .attachment-img{float:left;height:auto;max-height:100px;max-width:100px}.attachment-block .attachment-pushed{margin-left:110px}.attachment-block .attachment-heading{margin:0}.attachment-block .attachment-text{color:#495057}.card>.loading-img,.card>.overlay,.info-box>.loading-img,.info-box>.overlay,.overlay-wrapper>.loading-img,.overlay-wrapper>.overlay,.small-box>.loading-img,.small-box>.overlay{height:100%;left:0;position:absolute;top:0;width:100%}.card .overlay,.info-box .overlay,.overlay-wrapper .overlay,.small-box .overlay{border-radius:.25rem;align-items:center;background:hsla(0,0%,100%,.7);display:flex;justify-content:center;z-index:50}.card .overlay>.fa,.card .overlay>.fab,.card .overlay>.far,.card .overlay>.fas,.card .overlay>.glyphicon,.card .overlay>.ion,.info-box .overlay>.fa,.info-box .overlay>.fab,.info-box .overlay>.far,.info-box .overlay>.fas,.info-box .overlay>.glyphicon,.info-box .overlay>.ion,.overlay-wrapper .overlay>.fa,.overlay-wrapper .overlay>.fab,.overlay-wrapper .overlay>.far,.overlay-wrapper .overlay>.fas,.overlay-wrapper .overlay>.glyphicon,.overlay-wrapper .overlay>.ion,.small-box .overlay>.fa,.small-box .overlay>.fab,.small-box .overlay>.far,.small-box .overlay>.fas,.small-box .overlay>.glyphicon,.small-box .overlay>.ion{color:#343a40}.card .overlay.dark,.info-box .overlay.dark,.overlay-wrapper .overlay.dark,.small-box .overlay.dark{background:rgba(0,0,0,.5)}.card .overlay.dark>.fa,.card .overlay.dark>.fab,.card .overlay.dark>.far,.card .overlay.dark>.fas,.card .overlay.dark>.glyphicon,.card .overlay.dark>.ion,.info-box .overlay.dark>.fa,.info-box .overlay.dark>.fab,.info-box .overlay.dark>.far,.info-box .overlay.dark>.fas,.info-box .overlay.dark>.glyphicon,.info-box .overlay.dark>.ion,.overlay-wrapper .overlay.dark>.fa,.overlay-wrapper .overlay.dark>.fab,.overlay-wrapper .overlay.dark>.far,.overlay-wrapper .overlay.dark>.fas,.overlay-wrapper .overlay.dark>.glyphicon,.overlay-wrapper .overlay.dark>.ion,.small-box .overlay.dark>.fa,.small-box .overlay.dark>.fab,.small-box .overlay.dark>.far,.small-box .overlay.dark>.fas,.small-box .overlay.dark>.glyphicon,.small-box .overlay.dark>.ion{color:#ced4da}.tab-pane>.overlay-wrapper{position:relative}.tab-pane>.overlay-wrapper>.overlay{border-top-left-radius:0;border-top-right-radius:0;flex-direction:column;margin-top:-1.25rem;margin-left:-1.25rem;height:calc(100% + 2.5rem);width:calc(100% + 2.5rem)}.tab-pane>.overlay-wrapper>.overlay.dark{color:#fff}.ribbon-wrapper{height:70px;overflow:hidden;position:absolute;right:-2px;top:-2px;width:70px;z-index:10}.ribbon-wrapper.ribbon-lg{height:120px;width:120px}.ribbon-wrapper.ribbon-lg .ribbon{right:0;top:26px;width:160px}.ribbon-wrapper.ribbon-xl{height:180px;width:180px}.ribbon-wrapper.ribbon-xl .ribbon{right:4px;top:47px;width:240px}.ribbon-wrapper .ribbon{box-shadow:0 0 3px rgba(0,0,0,.3);font-size:.8rem;line-height:100%;padding:.375rem 0;position:relative;right:-2px;text-align:center;text-shadow:0 -1px 0 rgba(0,0,0,.4);text-transform:uppercase;top:10px;transform:rotate(45deg);width:90px}.ribbon-wrapper .ribbon:after,.ribbon-wrapper .ribbon:before{border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #9e9e9e;bottom:-3px;content:"";position:absolute}.ribbon-wrapper .ribbon:before{left:0}.ribbon-wrapper .ribbon:after{right:0}.back-to-top{bottom:1.25rem;position:fixed;right:1.25rem;z-index:1032}.back-to-top:focus{box-shadow:none}pre{padding:.75rem}blockquote{background:#fff;border-left:.7rem solid #007bff;margin:1.5em .7rem;padding:.5em .7rem}.box blockquote{background:#e9ecef}blockquote p:last-child{margin-bottom:0}blockquote h1,blockquote h2,blockquote h3,blockquote h4,blockquote h5,blockquote h6{color:#007bff;font-size:1.25rem;font-weight:600}blockquote.quote-primary{border-color:#007bff}blockquote.quote-primary h1,blockquote.quote-primary h2,blockquote.quote-primary h3,blockquote.quote-primary h4,blockquote.quote-primary h5,blockquote.quote-primary h6{color:#007bff}blockquote.quote-secondary{border-color:#6c757d}blockquote.quote-secondary h1,blockquote.quote-secondary h2,blockquote.quote-secondary h3,blockquote.quote-secondary h4,blockquote.quote-secondary h5,blockquote.quote-secondary h6{color:#6c757d}blockquote.quote-success{border-color:#28a745}blockquote.quote-success h1,blockquote.quote-success h2,blockquote.quote-success h3,blockquote.quote-success h4,blockquote.quote-success h5,blockquote.quote-success h6{color:#28a745}blockquote.quote-info{border-color:#17a2b8}blockquote.quote-info h1,blockquote.quote-info h2,blockquote.quote-info h3,blockquote.quote-info h4,blockquote.quote-info h5,blockquote.quote-info h6{color:#17a2b8}blockquote.quote-warning{border-color:#ffc107}blockquote.quote-warning h1,blockquote.quote-warning h2,blockquote.quote-warning h3,blockquote.quote-warning h4,blockquote.quote-warning h5,blockquote.quote-warning h6{color:#ffc107}blockquote.quote-danger{border-color:#dc3545}blockquote.quote-danger h1,blockquote.quote-danger h2,blockquote.quote-danger h3,blockquote.quote-danger h4,blockquote.quote-danger h5,blockquote.quote-danger h6{color:#dc3545}blockquote.quote-light{border-color:#f8f9fa}blockquote.quote-light h1,blockquote.quote-light h2,blockquote.quote-light h3,blockquote.quote-light h4,blockquote.quote-light h5,blockquote.quote-light h6{color:#f8f9fa}blockquote.quote-dark{border-color:#343a40}blockquote.quote-dark h1,blockquote.quote-dark h2,blockquote.quote-dark h3,blockquote.quote-dark h4,blockquote.quote-dark h5,blockquote.quote-dark h6{color:#343a40}blockquote.quote-lightblue{border-color:#3c8dbc}blockquote.quote-lightblue h1,blockquote.quote-lightblue h2,blockquote.quote-lightblue h3,blockquote.quote-lightblue h4,blockquote.quote-lightblue h5,blockquote.quote-lightblue h6{color:#3c8dbc}blockquote.quote-navy{border-color:#001f3f}blockquote.quote-navy h1,blockquote.quote-navy h2,blockquote.quote-navy h3,blockquote.quote-navy h4,blockquote.quote-navy h5,blockquote.quote-navy h6{color:#001f3f}blockquote.quote-olive{border-color:#3d9970}blockquote.quote-olive h1,blockquote.quote-olive h2,blockquote.quote-olive h3,blockquote.quote-olive h4,blockquote.quote-olive h5,blockquote.quote-olive h6{color:#3d9970}blockquote.quote-lime{border-color:#01ff70}blockquote.quote-lime h1,blockquote.quote-lime h2,blockquote.quote-lime h3,blockquote.quote-lime h4,blockquote.quote-lime h5,blockquote.quote-lime h6{color:#01ff70}blockquote.quote-fuchsia{border-color:#f012be}blockquote.quote-fuchsia h1,blockquote.quote-fuchsia h2,blockquote.quote-fuchsia h3,blockquote.quote-fuchsia h4,blockquote.quote-fuchsia h5,blockquote.quote-fuchsia h6{color:#f012be}blockquote.quote-maroon{border-color:#d81b60}blockquote.quote-maroon h1,blockquote.quote-maroon h2,blockquote.quote-maroon h3,blockquote.quote-maroon h4,blockquote.quote-maroon h5,blockquote.quote-maroon h6{color:#d81b60}blockquote.quote-blue{border-color:#007bff}blockquote.quote-blue h1,blockquote.quote-blue h2,blockquote.quote-blue h3,blockquote.quote-blue h4,blockquote.quote-blue h5,blockquote.quote-blue h6{color:#007bff}blockquote.quote-indigo{border-color:#6610f2}blockquote.quote-indigo h1,blockquote.quote-indigo h2,blockquote.quote-indigo h3,blockquote.quote-indigo h4,blockquote.quote-indigo h5,blockquote.quote-indigo h6{color:#6610f2}blockquote.quote-purple{border-color:#6f42c1}blockquote.quote-purple h1,blockquote.quote-purple h2,blockquote.quote-purple h3,blockquote.quote-purple h4,blockquote.quote-purple h5,blockquote.quote-purple h6{color:#6f42c1}blockquote.quote-pink{border-color:#e83e8c}blockquote.quote-pink h1,blockquote.quote-pink h2,blockquote.quote-pink h3,blockquote.quote-pink h4,blockquote.quote-pink h5,blockquote.quote-pink h6{color:#e83e8c}blockquote.quote-red{border-color:#dc3545}blockquote.quote-red h1,blockquote.quote-red h2,blockquote.quote-red h3,blockquote.quote-red h4,blockquote.quote-red h5,blockquote.quote-red h6{color:#dc3545}blockquote.quote-orange{border-color:#fd7e14}blockquote.quote-orange h1,blockquote.quote-orange h2,blockquote.quote-orange h3,blockquote.quote-orange h4,blockquote.quote-orange h5,blockquote.quote-orange h6{color:#fd7e14}blockquote.quote-yellow{border-color:#ffc107}blockquote.quote-yellow h1,blockquote.quote-yellow h2,blockquote.quote-yellow h3,blockquote.quote-yellow h4,blockquote.quote-yellow h5,blockquote.quote-yellow h6{color:#ffc107}blockquote.quote-green{border-color:#28a745}blockquote.quote-green h1,blockquote.quote-green h2,blockquote.quote-green h3,blockquote.quote-green h4,blockquote.quote-green h5,blockquote.quote-green h6{color:#28a745}blockquote.quote-teal{border-color:#20c997}blockquote.quote-teal h1,blockquote.quote-teal h2,blockquote.quote-teal h3,blockquote.quote-teal h4,blockquote.quote-teal h5,blockquote.quote-teal h6{color:#20c997}blockquote.quote-cyan{border-color:#17a2b8}blockquote.quote-cyan h1,blockquote.quote-cyan h2,blockquote.quote-cyan h3,blockquote.quote-cyan h4,blockquote.quote-cyan h5,blockquote.quote-cyan h6{color:#17a2b8}blockquote.quote-white{border-color:#fff}blockquote.quote-white h1,blockquote.quote-white h2,blockquote.quote-white h3,blockquote.quote-white h4,blockquote.quote-white h5,blockquote.quote-white h6{color:#fff}blockquote.quote-gray{border-color:#6c757d}blockquote.quote-gray h1,blockquote.quote-gray h2,blockquote.quote-gray h3,blockquote.quote-gray h4,blockquote.quote-gray h5,blockquote.quote-gray h6{color:#6c757d}blockquote.quote-gray-dark{border-color:#343a40}blockquote.quote-gray-dark h1,blockquote.quote-gray-dark h2,blockquote.quote-gray-dark h3,blockquote.quote-gray-dark h4,blockquote.quote-gray-dark h5,blockquote.quote-gray-dark h6{color:#343a40}.tab-custom-content{border-top:1px solid #dee2e6;margin-top:.5rem;padding-top:.5rem}.nav+.tab-custom-content{border-top:none;border-bottom:1px solid #dee2e6;margin-top:0;margin-bottom:.5rem;padding-bottom:.5rem}.badge-btn{border-radius:.15rem;font-size:.75rem;font-weight:400;padding:.25rem .5rem}.badge-btn.badge-pill{padding:.375rem .6rem}@media print{.content-header,.main-header,.main-sidebar,.no-print{display:none!important}.content-wrapper,.main-footer{transform:translate(0);margin-left:0!important;min-height:0!important}.layout-fixed .content-wrapper{padding-top:0!important}.invoice{border:0;margin:0;padding:0;width:100%}.invoice-col{float:left;width:33.3333333%}.table-responsive{overflow:auto}.table-responsive>.table tr td,.table-responsive>.table tr th{white-space:normal!important}}.text-bold,.text-bold.table td,.text-bold.table th{font-weight:700}.text-xs{font-size:.75rem!important}.text-sm{font-size:.875rem!important}.text-md{font-size:1rem!important}.text-lg{font-size:1.25rem!important}.text-xl{font-size:2rem!important}.text-lightblue{color:#3c8dbc!important}.text-navy{color:#001f3f!important}.text-olive{color:#3d9970!important}.text-lime{color:#01ff70!important}.text-fuchsia{color:#f012be!important}.text-maroon{color:#d81b60!important}.text-blue{color:#007bff!important}.text-indigo{color:#6610f2!important}.text-purple{color:#6f42c1!important}.text-pink{color:#e83e8c!important}.text-red{color:#dc3545!important}.text-orange{color:#fd7e14!important}.text-yellow{color:#ffc107!important}.text-green{color:#28a745!important}.text-teal{color:#20c997!important}.text-cyan{color:#17a2b8!important}.text-white{color:#fff!important}.text-gray{color:#6c757d!important}.text-gray-dark{color:#343a40!important}.elevation-0{box-shadow:none!important}.elevation-1{box-shadow:0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24)!important}.elevation-2{box-shadow:0 3px 6px rgba(0,0,0,.16),0 3px 6px rgba(0,0,0,.23)!important}.elevation-3{box-shadow:0 10px 20px rgba(0,0,0,.19),0 6px 6px rgba(0,0,0,.23)!important}.elevation-4{box-shadow:0 14px 28px rgba(0,0,0,.25),0 10px 10px rgba(0,0,0,.22)!important}.elevation-5{box-shadow:0 19px 38px rgba(0,0,0,.3),0 15px 12px rgba(0,0,0,.22)!important}.bg-primary{background-color:#007bff!important}.bg-primary,.bg-primary>a{color:#fff!important}.bg-primary.btn:hover{border-color:#0062cc;color:#ececec}.bg-primary.btn.active,.bg-primary.btn:active,.bg-primary.btn:not(:disabled):not(.disabled).active,.bg-primary.btn:not(:disabled):not(.disabled):active{background-color:#0062cc!important;border-color:#005cbf;color:#fff}.bg-secondary{background-color:#6c757d!important}.bg-secondary,.bg-secondary>a{color:#fff!important}.bg-secondary.btn:hover{border-color:#545b62;color:#ececec}.bg-secondary.btn.active,.bg-secondary.btn:active,.bg-secondary.btn:not(:disabled):not(.disabled).active,.bg-secondary.btn:not(:disabled):not(.disabled):active{background-color:#545b62!important;border-color:#4e555b;color:#fff}.bg-success{background-color:#28a745!important}.bg-success,.bg-success>a{color:#fff!important}.bg-success.btn:hover{border-color:#1e7e34;color:#ececec}.bg-success.btn.active,.bg-success.btn:active,.bg-success.btn:not(:disabled):not(.disabled).active,.bg-success.btn:not(:disabled):not(.disabled):active{background-color:#1e7e34!important;border-color:#1c7430;color:#fff}.bg-info{background-color:#17a2b8!important}.bg-info,.bg-info>a{color:#fff!important}.bg-info.btn:hover{border-color:#117a8b;color:#ececec}.bg-info.btn.active,.bg-info.btn:active,.bg-info.btn:not(:disabled):not(.disabled).active,.bg-info.btn:not(:disabled):not(.disabled):active{background-color:#117a8b!important;border-color:#10707f;color:#fff}.bg-warning{background-color:#ffc107!important}.bg-warning,.bg-warning>a{color:#1f2d3d!important}.bg-warning.btn:hover{border-color:#d39e00;color:#121a24}.bg-warning.btn.active,.bg-warning.btn:active,.bg-warning.btn:not(:disabled):not(.disabled).active,.bg-warning.btn:not(:disabled):not(.disabled):active{background-color:#d39e00!important;border-color:#c69500;color:#1f2d3d}.bg-danger{background-color:#dc3545!important}.bg-danger,.bg-danger>a{color:#fff!important}.bg-danger.btn:hover{border-color:#bd2130;color:#ececec}.bg-danger.btn.active,.bg-danger.btn:active,.bg-danger.btn:not(:disabled):not(.disabled).active,.bg-danger.btn:not(:disabled):not(.disabled):active{background-color:#bd2130!important;border-color:#b21f2d;color:#fff}.bg-light{background-color:#f8f9fa!important}.bg-light,.bg-light>a{color:#1f2d3d!important}.bg-light.btn:hover{border-color:#dae0e5;color:#121a24}.bg-light.btn.active,.bg-light.btn:active,.bg-light.btn:not(:disabled):not(.disabled).active,.bg-light.btn:not(:disabled):not(.disabled):active{background-color:#dae0e5!important;border-color:#d3d9df;color:#1f2d3d}.bg-dark{background-color:#343a40!important}.bg-dark,.bg-dark>a{color:#fff!important}.bg-dark.btn:hover{border-color:#1d2124;color:#ececec}.bg-dark.btn.active,.bg-dark.btn:active,.bg-dark.btn:not(:disabled):not(.disabled).active,.bg-dark.btn:not(:disabled):not(.disabled):active{background-color:#1d2124!important;border-color:#171a1d;color:#fff}.bg-lightblue{background-color:#3c8dbc!important}.bg-lightblue,.bg-lightblue>a{color:#fff!important}.bg-lightblue.btn:hover{border-color:#307095;color:#ececec}.bg-lightblue.btn.active,.bg-lightblue.btn:active,.bg-lightblue.btn:not(:disabled):not(.disabled).active,.bg-lightblue.btn:not(:disabled):not(.disabled):active{background-color:#307095!important;border-color:#2d698c;color:#fff}.bg-navy{background-color:#001f3f!important}.bg-navy,.bg-navy>a{color:#fff!important}.bg-navy.btn:hover{border-color:#00060c;color:#ececec}.bg-navy.btn.active,.bg-navy.btn:active,.bg-navy.btn:not(:disabled):not(.disabled).active,.bg-navy.btn:not(:disabled):not(.disabled):active{background-color:#00060c!important;border-color:#000;color:#fff}.bg-olive{background-color:#3d9970!important}.bg-olive,.bg-olive>a{color:#fff!important}.bg-olive.btn:hover{border-color:#2e7555;color:#ececec}.bg-olive.btn.active,.bg-olive.btn:active,.bg-olive.btn:not(:disabled):not(.disabled).active,.bg-olive.btn:not(:disabled):not(.disabled):active{background-color:#2e7555!important;border-color:#2b6b4f;color:#fff}.bg-lime{background-color:#01ff70!important}.bg-lime,.bg-lime>a{color:#1f2d3d!important}.bg-lime.btn:hover{border-color:#00cd5a;color:#121a24}.bg-lime.btn.active,.bg-lime.btn:active,.bg-lime.btn:not(:disabled):not(.disabled).active,.bg-lime.btn:not(:disabled):not(.disabled):active{background-color:#00cd5a!important;border-color:#00c054;color:#fff}.bg-fuchsia{background-color:#f012be!important}.bg-fuchsia,.bg-fuchsia>a{color:#fff!important}.bg-fuchsia.btn:hover{border-color:#c30c9a;color:#ececec}.bg-fuchsia.btn.active,.bg-fuchsia.btn:active,.bg-fuchsia.btn:not(:disabled):not(.disabled).active,.bg-fuchsia.btn:not(:disabled):not(.disabled):active{background-color:#c30c9a!important;border-color:#b70c90;color:#fff}.bg-maroon{background-color:#d81b60!important}.bg-maroon,.bg-maroon>a{color:#fff!important}.bg-maroon.btn:hover{border-color:#ab154c;color:#ececec}.bg-maroon.btn.active,.bg-maroon.btn:active,.bg-maroon.btn:not(:disabled):not(.disabled).active,.bg-maroon.btn:not(:disabled):not(.disabled):active{background-color:#ab154c!important;border-color:#9f1447;color:#fff}.bg-blue{background-color:#007bff!important}.bg-blue,.bg-blue>a{color:#fff!important}.bg-blue.btn:hover{border-color:#0062cc;color:#ececec}.bg-blue.btn.active,.bg-blue.btn:active,.bg-blue.btn:not(:disabled):not(.disabled).active,.bg-blue.btn:not(:disabled):not(.disabled):active{background-color:#0062cc!important;border-color:#005cbf;color:#fff}.bg-indigo{background-color:#6610f2!important}.bg-indigo,.bg-indigo>a{color:#fff!important}.bg-indigo.btn:hover{border-color:#510bc4;color:#ececec}.bg-indigo.btn.active,.bg-indigo.btn:active,.bg-indigo.btn:not(:disabled):not(.disabled).active,.bg-indigo.btn:not(:disabled):not(.disabled):active{background-color:#510bc4!important;border-color:#4c0ab8;color:#fff}.bg-purple{background-color:#6f42c1!important}.bg-purple,.bg-purple>a{color:#fff!important}.bg-purple.btn:hover{border-color:#59339d;color:#ececec}.bg-purple.btn.active,.bg-purple.btn:active,.bg-purple.btn:not(:disabled):not(.disabled).active,.bg-purple.btn:not(:disabled):not(.disabled):active{background-color:#59339d!important;border-color:#533093;color:#fff}.bg-pink{background-color:#e83e8c!important}.bg-pink,.bg-pink>a{color:#fff!important}.bg-pink.btn:hover{border-color:#d91a72;color:#ececec}.bg-pink.btn.active,.bg-pink.btn:active,.bg-pink.btn:not(:disabled):not(.disabled).active,.bg-pink.btn:not(:disabled):not(.disabled):active{background-color:#d91a72!important;border-color:#ce196c;color:#fff}.bg-red{background-color:#dc3545!important}.bg-red,.bg-red>a{color:#fff!important}.bg-red.btn:hover{border-color:#bd2130;color:#ececec}.bg-red.btn.active,.bg-red.btn:active,.bg-red.btn:not(:disabled):not(.disabled).active,.bg-red.btn:not(:disabled):not(.disabled):active{background-color:#bd2130!important;border-color:#b21f2d;color:#fff}.bg-orange{background-color:#fd7e14!important}.bg-orange,.bg-orange>a{color:#1f2d3d!important}.bg-orange.btn:hover{border-color:#dc6502;color:#121a24}.bg-orange.btn.active,.bg-orange.btn:active,.bg-orange.btn:not(:disabled):not(.disabled).active,.bg-orange.btn:not(:disabled):not(.disabled):active{background-color:#dc6502!important;border-color:#cf5f02;color:#fff}.bg-yellow{background-color:#ffc107!important}.bg-yellow,.bg-yellow>a{color:#1f2d3d!important}.bg-yellow.btn:hover{border-color:#d39e00;color:#121a24}.bg-yellow.btn.active,.bg-yellow.btn:active,.bg-yellow.btn:not(:disabled):not(.disabled).active,.bg-yellow.btn:not(:disabled):not(.disabled):active{background-color:#d39e00!important;border-color:#c69500;color:#1f2d3d}.bg-green{background-color:#28a745!important}.bg-green,.bg-green>a{color:#fff!important}.bg-green.btn:hover{border-color:#1e7e34;color:#ececec}.bg-green.btn.active,.bg-green.btn:active,.bg-green.btn:not(:disabled):not(.disabled).active,.bg-green.btn:not(:disabled):not(.disabled):active{background-color:#1e7e34!important;border-color:#1c7430;color:#fff}.bg-teal{background-color:#20c997!important}.bg-teal,.bg-teal>a{color:#fff!important}.bg-teal.btn:hover{border-color:#199d76;color:#ececec}.bg-teal.btn.active,.bg-teal.btn:active,.bg-teal.btn:not(:disabled):not(.disabled).active,.bg-teal.btn:not(:disabled):not(.disabled):active{background-color:#199d76!important;border-color:#17926e;color:#fff}.bg-cyan{background-color:#17a2b8!important}.bg-cyan,.bg-cyan>a{color:#fff!important}.bg-cyan.btn:hover{border-color:#117a8b;color:#ececec}.bg-cyan.btn.active,.bg-cyan.btn:active,.bg-cyan.btn:not(:disabled):not(.disabled).active,.bg-cyan.btn:not(:disabled):not(.disabled):active{background-color:#117a8b!important;border-color:#10707f;color:#fff}.bg-white{background-color:#fff!important}.bg-white,.bg-white>a{color:#1f2d3d!important}.bg-white.btn:hover{border-color:#e6e6e6;color:#121a24}.bg-white.btn.active,.bg-white.btn:active,.bg-white.btn:not(:disabled):not(.disabled).active,.bg-white.btn:not(:disabled):not(.disabled):active{background-color:#e6e6e6!important;border-color:#dfdfdf;color:#1f2d3d}.bg-gray{background-color:#6c757d!important}.bg-gray,.bg-gray>a{color:#fff!important}.bg-gray.btn:hover{border-color:#545b62;color:#ececec}.bg-gray.btn.active,.bg-gray.btn:active,.bg-gray.btn:not(:disabled):not(.disabled).active,.bg-gray.btn:not(:disabled):not(.disabled):active{background-color:#545b62!important;border-color:#4e555b;color:#fff}.bg-gray-dark{background-color:#343a40!important}.bg-gray-dark,.bg-gray-dark>a{color:#fff!important}.bg-gray-dark.btn:hover{border-color:#1d2124;color:#ececec}.bg-gray-dark.btn.active,.bg-gray-dark.btn:active,.bg-gray-dark.btn:not(:disabled):not(.disabled).active,.bg-gray-dark.btn:not(:disabled):not(.disabled):active{background-color:#1d2124!important;border-color:#171a1d;color:#fff}.bg-gray{background-color:#adb5bd;color:#1f2d3d}.bg-gray-light{background-color:#f2f4f5;color:#1f2d3d!important}.bg-black{background-color:#000;color:#fff!important}.bg-white{background-color:#fff;color:#1f2d3d!important}.bg-gradient-primary{color:#fff;background:#007bff linear-gradient(180deg,#268fff,#007bff) repeat-x!important}.bg-gradient-primary.btn.disabled,.bg-gradient-primary.btn:disabled,.bg-gradient-primary.btn:not(:disabled):not(.disabled).active,.bg-gradient-primary.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-primary.btn.dropdown-toggle{background-image:none!important}.bg-gradient-primary.btn:hover{border-color:#0062cc;color:#ececec;background:#0069d9 linear-gradient(180deg,#267fde,#0069d9) repeat-x!important}.bg-gradient-primary.btn.active,.bg-gradient-primary.btn:active,.bg-gradient-primary.btn:not(:disabled):not(.disabled).active,.bg-gradient-primary.btn:not(:disabled):not(.disabled):active{border-color:#005cbf;color:#fff;background:#0062cc linear-gradient(180deg,#267ad4,#0062cc) repeat-x!important}.bg-gradient-secondary{color:#fff;background:#6c757d linear-gradient(180deg,#828a91,#6c757d) repeat-x!important}.bg-gradient-secondary.btn.disabled,.bg-gradient-secondary.btn:disabled,.bg-gradient-secondary.btn:not(:disabled):not(.disabled).active,.bg-gradient-secondary.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-secondary.btn.dropdown-toggle{background-image:none!important}.bg-gradient-secondary.btn:hover{border-color:#545b62;color:#ececec;background:#5a6268 linear-gradient(180deg,#73797f,#5a6268) repeat-x!important}.bg-gradient-secondary.btn.active,.bg-gradient-secondary.btn:active,.bg-gradient-secondary.btn:not(:disabled):not(.disabled).active,.bg-gradient-secondary.btn:not(:disabled):not(.disabled):active{border-color:#4e555b;color:#fff;background:#545b62 linear-gradient(180deg,#6e7479,#545b62) repeat-x!important}.bg-gradient-success{color:#fff;background:#28a745 linear-gradient(180deg,#48b461,#28a745) repeat-x!important}.bg-gradient-success.btn.disabled,.bg-gradient-success.btn:disabled,.bg-gradient-success.btn:not(:disabled):not(.disabled).active,.bg-gradient-success.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-success.btn.dropdown-toggle{background-image:none!important}.bg-gradient-success.btn:hover{border-color:#1e7e34;color:#ececec;background:#218838 linear-gradient(180deg,#429a56,#218838) repeat-x!important}.bg-gradient-success.btn.active,.bg-gradient-success.btn:active,.bg-gradient-success.btn:not(:disabled):not(.disabled).active,.bg-gradient-success.btn:not(:disabled):not(.disabled):active{border-color:#1c7430;color:#fff;background:#1e7e34 linear-gradient(180deg,#409152,#1e7e34) repeat-x!important}.bg-gradient-info{color:#fff;background:#17a2b8 linear-gradient(180deg,#3ab0c3,#17a2b8) repeat-x!important}.bg-gradient-info.btn.disabled,.bg-gradient-info.btn:disabled,.bg-gradient-info.btn:not(:disabled):not(.disabled).active,.bg-gradient-info.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-info.btn.dropdown-toggle{background-image:none!important}.bg-gradient-info.btn:hover{border-color:#117a8b;color:#ececec;background:#138496 linear-gradient(180deg,#3697a6,#138496) repeat-x!important}.bg-gradient-info.btn.active,.bg-gradient-info.btn:active,.bg-gradient-info.btn:not(:disabled):not(.disabled).active,.bg-gradient-info.btn:not(:disabled):not(.disabled):active{border-color:#10707f;color:#fff;background:#117a8b linear-gradient(180deg,#358e9c,#117a8b) repeat-x!important}.bg-gradient-warning{color:#1f2d3d;background:#ffc107 linear-gradient(180deg,#ffca2c,#ffc107) repeat-x!important}.bg-gradient-warning.btn.disabled,.bg-gradient-warning.btn:disabled,.bg-gradient-warning.btn:not(:disabled):not(.disabled).active,.bg-gradient-warning.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-warning.btn.dropdown-toggle{background-image:none!important}.bg-gradient-warning.btn:hover{border-color:#d39e00;color:#121a24;background:#e0a800 linear-gradient(180deg,#e4b526,#e0a800) repeat-x!important}.bg-gradient-warning.btn.active,.bg-gradient-warning.btn:active,.bg-gradient-warning.btn:not(:disabled):not(.disabled).active,.bg-gradient-warning.btn:not(:disabled):not(.disabled):active{border-color:#c69500;color:#1f2d3d;background:#d39e00 linear-gradient(180deg,#daad26,#d39e00) repeat-x!important}.bg-gradient-danger{color:#fff;background:#dc3545 linear-gradient(180deg,#e15361,#dc3545) repeat-x!important}.bg-gradient-danger.btn.disabled,.bg-gradient-danger.btn:disabled,.bg-gradient-danger.btn:not(:disabled):not(.disabled).active,.bg-gradient-danger.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-danger.btn.dropdown-toggle{background-image:none!important}.bg-gradient-danger.btn:hover{border-color:#bd2130;color:#ececec;background:#c82333 linear-gradient(180deg,#d04451,#c82333) repeat-x!important}.bg-gradient-danger.btn.active,.bg-gradient-danger.btn:active,.bg-gradient-danger.btn:not(:disabled):not(.disabled).active,.bg-gradient-danger.btn:not(:disabled):not(.disabled):active{border-color:#b21f2d;color:#fff;background:#bd2130 linear-gradient(180deg,#c7424f,#bd2130) repeat-x!important}.bg-gradient-light{color:#1f2d3d;background:#f8f9fa linear-gradient(180deg,#f9fafb,#f8f9fa) repeat-x!important}.bg-gradient-light.btn.disabled,.bg-gradient-light.btn:disabled,.bg-gradient-light.btn:not(:disabled):not(.disabled).active,.bg-gradient-light.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-light.btn.dropdown-toggle{background-image:none!important}.bg-gradient-light.btn:hover{border-color:#dae0e5;color:#121a24;background:#e2e6ea linear-gradient(180deg,#e6eaed,#e2e6ea) repeat-x!important}.bg-gradient-light.btn.active,.bg-gradient-light.btn:active,.bg-gradient-light.btn:not(:disabled):not(.disabled).active,.bg-gradient-light.btn:not(:disabled):not(.disabled):active{border-color:#d3d9df;color:#1f2d3d;background:#dae0e5 linear-gradient(180deg,#e0e4e9,#dae0e5) repeat-x!important}.bg-gradient-dark{color:#fff;background:#343a40 linear-gradient(180deg,#52585d,#343a40) repeat-x!important}.bg-gradient-dark.btn.disabled,.bg-gradient-dark.btn:disabled,.bg-gradient-dark.btn:not(:disabled):not(.disabled).active,.bg-gradient-dark.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-dark.btn.dropdown-toggle{background-image:none!important}.bg-gradient-dark.btn:hover{border-color:#1d2124;color:#ececec;background:#23272b linear-gradient(180deg,#44474b,#23272b) repeat-x!important}.bg-gradient-dark.btn.active,.bg-gradient-dark.btn:active,.bg-gradient-dark.btn:not(:disabled):not(.disabled).active,.bg-gradient-dark.btn:not(:disabled):not(.disabled):active{border-color:#171a1d;color:#fff;background:#1d2124 linear-gradient(180deg,#3f4245,#1d2124) repeat-x!important}.bg-gradient-lightblue{color:#fff;background:#3c8dbc linear-gradient(180deg,#599ec6,#3c8dbc) repeat-x!important}.bg-gradient-lightblue.btn.disabled,.bg-gradient-lightblue.btn:disabled,.bg-gradient-lightblue.btn:not(:disabled):not(.disabled).active,.bg-gradient-lightblue.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-lightblue.btn.dropdown-toggle{background-image:none!important}.bg-gradient-lightblue.btn:hover{border-color:#307095;color:#ececec;background:#33779f linear-gradient(180deg,#518cad,#33779f) repeat-x!important}.bg-gradient-lightblue.btn.active,.bg-gradient-lightblue.btn:active,.bg-gradient-lightblue.btn:not(:disabled):not(.disabled).active,.bg-gradient-lightblue.btn:not(:disabled):not(.disabled):active{border-color:#2d698c;color:#fff;background:#307095 linear-gradient(180deg,#4f85a5,#307095) repeat-x!important}.bg-gradient-navy{color:#fff;background:#001f3f linear-gradient(180deg,#26415c,#001f3f) repeat-x!important}.bg-gradient-navy.btn.disabled,.bg-gradient-navy.btn:disabled,.bg-gradient-navy.btn:not(:disabled):not(.disabled).active,.bg-gradient-navy.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-navy.btn.dropdown-toggle{background-image:none!important}.bg-gradient-navy.btn:hover{border-color:#00060c;color:#ececec;background:#000c19 linear-gradient(180deg,#26313b,#000c19) repeat-x!important}.bg-gradient-navy.btn.active,.bg-gradient-navy.btn:active,.bg-gradient-navy.btn:not(:disabled):not(.disabled).active,.bg-gradient-navy.btn:not(:disabled):not(.disabled):active{border-color:#000;color:#fff;background:#00060c linear-gradient(180deg,#262b30,#00060c) repeat-x!important}.bg-gradient-olive{color:#fff;background:#3d9970 linear-gradient(180deg,#5aa885,#3d9970) repeat-x!important}.bg-gradient-olive.btn.disabled,.bg-gradient-olive.btn:disabled,.bg-gradient-olive.btn:not(:disabled):not(.disabled).active,.bg-gradient-olive.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-olive.btn.dropdown-toggle{background-image:none!important}.bg-gradient-olive.btn:hover{border-color:#2e7555;color:#ececec;background:#327e5c linear-gradient(180deg,#519174,#327e5c) repeat-x!important}.bg-gradient-olive.btn.active,.bg-gradient-olive.btn:active,.bg-gradient-olive.btn:not(:disabled):not(.disabled).active,.bg-gradient-olive.btn:not(:disabled):not(.disabled):active{border-color:#2b6b4f;color:#fff;background:#2e7555 linear-gradient(180deg,#4e896f,#2e7555) repeat-x!important}.bg-gradient-lime{color:#1f2d3d;background:#01ff70 linear-gradient(180deg,#27ff85,#01ff70) repeat-x!important}.bg-gradient-lime.btn.disabled,.bg-gradient-lime.btn:disabled,.bg-gradient-lime.btn:not(:disabled):not(.disabled).active,.bg-gradient-lime.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-lime.btn.dropdown-toggle{background-image:none!important}.bg-gradient-lime.btn:hover{border-color:#00cd5a;color:#121a24;background:#00da5f linear-gradient(180deg,#26df77,#00da5f) repeat-x!important}.bg-gradient-lime.btn.active,.bg-gradient-lime.btn:active,.bg-gradient-lime.btn:not(:disabled):not(.disabled).active,.bg-gradient-lime.btn:not(:disabled):not(.disabled):active{border-color:#00c054;color:#fff;background:#00cd5a linear-gradient(180deg,#26d572,#00cd5a) repeat-x!important}.bg-gradient-fuchsia{color:#fff;background:#f012be linear-gradient(180deg,#f236c8,#f012be) repeat-x!important}.bg-gradient-fuchsia.btn.disabled,.bg-gradient-fuchsia.btn:disabled,.bg-gradient-fuchsia.btn:not(:disabled):not(.disabled).active,.bg-gradient-fuchsia.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-fuchsia.btn.dropdown-toggle{background-image:none!important}.bg-gradient-fuchsia.btn:hover{border-color:#c30c9a;color:#ececec;background:#cf0da3 linear-gradient(180deg,#d631b1,#cf0da3) repeat-x!important}.bg-gradient-fuchsia.btn.active,.bg-gradient-fuchsia.btn:active,.bg-gradient-fuchsia.btn:not(:disabled):not(.disabled).active,.bg-gradient-fuchsia.btn:not(:disabled):not(.disabled):active{border-color:#b70c90;color:#fff;background:#c30c9a linear-gradient(180deg,#cc31a9,#c30c9a) repeat-x!important}.bg-gradient-maroon{color:#fff;background:#d81b60 linear-gradient(180deg,#de3d78,#d81b60) repeat-x!important}.bg-gradient-maroon.btn.disabled,.bg-gradient-maroon.btn:disabled,.bg-gradient-maroon.btn:not(:disabled):not(.disabled).active,.bg-gradient-maroon.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-maroon.btn.dropdown-toggle{background-image:none!important}.bg-gradient-maroon.btn:hover{border-color:#ab154c;color:#ececec;background:#b61751 linear-gradient(180deg,#c13a6b,#b61751) repeat-x!important}.bg-gradient-maroon.btn.active,.bg-gradient-maroon.btn:active,.bg-gradient-maroon.btn:not(:disabled):not(.disabled).active,.bg-gradient-maroon.btn:not(:disabled):not(.disabled):active{border-color:#9f1447;color:#fff;background:#ab154c linear-gradient(180deg,#b73867,#ab154c) repeat-x!important}.bg-gradient-blue{color:#fff;background:#007bff linear-gradient(180deg,#268fff,#007bff) repeat-x!important}.bg-gradient-blue.btn.disabled,.bg-gradient-blue.btn:disabled,.bg-gradient-blue.btn:not(:disabled):not(.disabled).active,.bg-gradient-blue.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-blue.btn.dropdown-toggle{background-image:none!important}.bg-gradient-blue.btn:hover{border-color:#0062cc;color:#ececec;background:#0069d9 linear-gradient(180deg,#267fde,#0069d9) repeat-x!important}.bg-gradient-blue.btn.active,.bg-gradient-blue.btn:active,.bg-gradient-blue.btn:not(:disabled):not(.disabled).active,.bg-gradient-blue.btn:not(:disabled):not(.disabled):active{border-color:#005cbf;color:#fff;background:#0062cc linear-gradient(180deg,#267ad4,#0062cc) repeat-x!important}.bg-gradient-indigo{color:#fff;background:#6610f2 linear-gradient(180deg,#7d34f4,#6610f2) repeat-x!important}.bg-gradient-indigo.btn.disabled,.bg-gradient-indigo.btn:disabled,.bg-gradient-indigo.btn:not(:disabled):not(.disabled).active,.bg-gradient-indigo.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-indigo.btn.dropdown-toggle{background-image:none!important}.bg-gradient-indigo.btn:hover{border-color:#510bc4;color:#ececec;background:#560bd0 linear-gradient(180deg,#7030d7,#560bd0) repeat-x!important}.bg-gradient-indigo.btn.active,.bg-gradient-indigo.btn:active,.bg-gradient-indigo.btn:not(:disabled):not(.disabled).active,.bg-gradient-indigo.btn:not(:disabled):not(.disabled):active{border-color:#4c0ab8;color:#fff;background:#510bc4 linear-gradient(180deg,#6b2fcd,#510bc4) repeat-x!important}.bg-gradient-purple{color:#fff;background:#6f42c1 linear-gradient(180deg,#855eca,#6f42c1) repeat-x!important}.bg-gradient-purple.btn.disabled,.bg-gradient-purple.btn:disabled,.bg-gradient-purple.btn:not(:disabled):not(.disabled).active,.bg-gradient-purple.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-purple.btn.dropdown-toggle{background-image:none!important}.bg-gradient-purple.btn:hover{border-color:#59339d;color:#ececec;background:#5e37a6 linear-gradient(180deg,#7655b4,#5e37a6) repeat-x!important}.bg-gradient-purple.btn.active,.bg-gradient-purple.btn:active,.bg-gradient-purple.btn:not(:disabled):not(.disabled).active,.bg-gradient-purple.btn:not(:disabled):not(.disabled):active{border-color:#533093;color:#fff;background:#59339d linear-gradient(180deg,#7252ab,#59339d) repeat-x!important}.bg-gradient-pink{color:#fff;background:#e83e8c linear-gradient(180deg,#eb5b9d,#e83e8c) repeat-x!important}.bg-gradient-pink.btn.disabled,.bg-gradient-pink.btn:disabled,.bg-gradient-pink.btn:not(:disabled):not(.disabled).active,.bg-gradient-pink.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-pink.btn.dropdown-toggle{background-image:none!important}.bg-gradient-pink.btn:hover{border-color:#d91a72;color:#ececec;background:#e41c78 linear-gradient(180deg,#e83e8c,#e41c78) repeat-x!important}.bg-gradient-pink.btn.active,.bg-gradient-pink.btn:active,.bg-gradient-pink.btn:not(:disabled):not(.disabled).active,.bg-gradient-pink.btn:not(:disabled):not(.disabled):active{border-color:#ce196c;color:#fff;background:#d91a72 linear-gradient(180deg,#df3c87,#d91a72) repeat-x!important}.bg-gradient-red{color:#fff;background:#dc3545 linear-gradient(180deg,#e15361,#dc3545) repeat-x!important}.bg-gradient-red.btn.disabled,.bg-gradient-red.btn:disabled,.bg-gradient-red.btn:not(:disabled):not(.disabled).active,.bg-gradient-red.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-red.btn.dropdown-toggle{background-image:none!important}.bg-gradient-red.btn:hover{border-color:#bd2130;color:#ececec;background:#c82333 linear-gradient(180deg,#d04451,#c82333) repeat-x!important}.bg-gradient-red.btn.active,.bg-gradient-red.btn:active,.bg-gradient-red.btn:not(:disabled):not(.disabled).active,.bg-gradient-red.btn:not(:disabled):not(.disabled):active{border-color:#b21f2d;color:#fff;background:#bd2130 linear-gradient(180deg,#c7424f,#bd2130) repeat-x!important}.bg-gradient-orange{color:#1f2d3d;background:#fd7e14 linear-gradient(180deg,#fd9137,#fd7e14) repeat-x!important}.bg-gradient-orange.btn.disabled,.bg-gradient-orange.btn:disabled,.bg-gradient-orange.btn:not(:disabled):not(.disabled).active,.bg-gradient-orange.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-orange.btn.dropdown-toggle{background-image:none!important}.bg-gradient-orange.btn:hover{border-color:#dc6502;color:#121a24;background:#e96b02 linear-gradient(180deg,#ec8128,#e96b02) repeat-x!important}.bg-gradient-orange.btn.active,.bg-gradient-orange.btn:active,.bg-gradient-orange.btn:not(:disabled):not(.disabled).active,.bg-gradient-orange.btn:not(:disabled):not(.disabled):active{border-color:#cf5f02;color:#fff;background:#dc6502 linear-gradient(180deg,#e17c28,#dc6502) repeat-x!important}.bg-gradient-yellow{color:#1f2d3d;background:#ffc107 linear-gradient(180deg,#ffca2c,#ffc107) repeat-x!important}.bg-gradient-yellow.btn.disabled,.bg-gradient-yellow.btn:disabled,.bg-gradient-yellow.btn:not(:disabled):not(.disabled).active,.bg-gradient-yellow.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-yellow.btn.dropdown-toggle{background-image:none!important}.bg-gradient-yellow.btn:hover{border-color:#d39e00;color:#121a24;background:#e0a800 linear-gradient(180deg,#e4b526,#e0a800) repeat-x!important}.bg-gradient-yellow.btn.active,.bg-gradient-yellow.btn:active,.bg-gradient-yellow.btn:not(:disabled):not(.disabled).active,.bg-gradient-yellow.btn:not(:disabled):not(.disabled):active{border-color:#c69500;color:#1f2d3d;background:#d39e00 linear-gradient(180deg,#daad26,#d39e00) repeat-x!important}.bg-gradient-green{color:#fff;background:#28a745 linear-gradient(180deg,#48b461,#28a745) repeat-x!important}.bg-gradient-green.btn.disabled,.bg-gradient-green.btn:disabled,.bg-gradient-green.btn:not(:disabled):not(.disabled).active,.bg-gradient-green.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-green.btn.dropdown-toggle{background-image:none!important}.bg-gradient-green.btn:hover{border-color:#1e7e34;color:#ececec;background:#218838 linear-gradient(180deg,#429a56,#218838) repeat-x!important}.bg-gradient-green.btn.active,.bg-gradient-green.btn:active,.bg-gradient-green.btn:not(:disabled):not(.disabled).active,.bg-gradient-green.btn:not(:disabled):not(.disabled):active{border-color:#1c7430;color:#fff;background:#1e7e34 linear-gradient(180deg,#409152,#1e7e34) repeat-x!important}.bg-gradient-teal{color:#fff;background:#20c997 linear-gradient(180deg,#41d1a7,#20c997) repeat-x!important}.bg-gradient-teal.btn.disabled,.bg-gradient-teal.btn:disabled,.bg-gradient-teal.btn:not(:disabled):not(.disabled).active,.bg-gradient-teal.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-teal.btn.dropdown-toggle{background-image:none!important}.bg-gradient-teal.btn:hover{border-color:#199d76;color:#ececec;background:#1ba87e linear-gradient(180deg,#3db592,#1ba87e) repeat-x!important}.bg-gradient-teal.btn.active,.bg-gradient-teal.btn:active,.bg-gradient-teal.btn:not(:disabled):not(.disabled).active,.bg-gradient-teal.btn:not(:disabled):not(.disabled):active{border-color:#17926e;color:#fff;background:#199d76 linear-gradient(180deg,#3bac8b,#199d76) repeat-x!important}.bg-gradient-cyan{color:#fff;background:#17a2b8 linear-gradient(180deg,#3ab0c3,#17a2b8) repeat-x!important}.bg-gradient-cyan.btn.disabled,.bg-gradient-cyan.btn:disabled,.bg-gradient-cyan.btn:not(:disabled):not(.disabled).active,.bg-gradient-cyan.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-cyan.btn.dropdown-toggle{background-image:none!important}.bg-gradient-cyan.btn:hover{border-color:#117a8b;color:#ececec;background:#138496 linear-gradient(180deg,#3697a6,#138496) repeat-x!important}.bg-gradient-cyan.btn.active,.bg-gradient-cyan.btn:active,.bg-gradient-cyan.btn:not(:disabled):not(.disabled).active,.bg-gradient-cyan.btn:not(:disabled):not(.disabled):active{border-color:#10707f;color:#fff;background:#117a8b linear-gradient(180deg,#358e9c,#117a8b) repeat-x!important}.bg-gradient-white{color:#1f2d3d;background:#fff linear-gradient(180deg,#fff,#fff) repeat-x!important}.bg-gradient-white.btn.disabled,.bg-gradient-white.btn:disabled,.bg-gradient-white.btn:not(:disabled):not(.disabled).active,.bg-gradient-white.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-white.btn.dropdown-toggle{background-image:none!important}.bg-gradient-white.btn:hover{border-color:#e6e6e6;color:#121a24;background:#ececec linear-gradient(180deg,#efefef,#ececec) repeat-x!important}.bg-gradient-white.btn.active,.bg-gradient-white.btn:active,.bg-gradient-white.btn:not(:disabled):not(.disabled).active,.bg-gradient-white.btn:not(:disabled):not(.disabled):active{border-color:#dfdfdf;color:#1f2d3d;background:#e6e6e6 linear-gradient(180deg,#e9e9e9,#e6e6e6) repeat-x!important}.bg-gradient-gray{color:#fff;background:#6c757d linear-gradient(180deg,#828a91,#6c757d) repeat-x!important}.bg-gradient-gray.btn.disabled,.bg-gradient-gray.btn:disabled,.bg-gradient-gray.btn:not(:disabled):not(.disabled).active,.bg-gradient-gray.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-gray.btn.dropdown-toggle{background-image:none!important}.bg-gradient-gray.btn:hover{border-color:#545b62;color:#ececec;background:#5a6268 linear-gradient(180deg,#73797f,#5a6268) repeat-x!important}.bg-gradient-gray.btn.active,.bg-gradient-gray.btn:active,.bg-gradient-gray.btn:not(:disabled):not(.disabled).active,.bg-gradient-gray.btn:not(:disabled):not(.disabled):active{border-color:#4e555b;color:#fff;background:#545b62 linear-gradient(180deg,#6e7479,#545b62) repeat-x!important}.bg-gradient-gray-dark{color:#fff;background:#343a40 linear-gradient(180deg,#52585d,#343a40) repeat-x!important}.bg-gradient-gray-dark.btn.disabled,.bg-gradient-gray-dark.btn:disabled,.bg-gradient-gray-dark.btn:not(:disabled):not(.disabled).active,.bg-gradient-gray-dark.btn:not(:disabled):not(.disabled):active,.show>.bg-gradient-gray-dark.btn.dropdown-toggle{background-image:none!important}.bg-gradient-gray-dark.btn:hover{border-color:#1d2124;color:#ececec;background:#23272b linear-gradient(180deg,#44474b,#23272b) repeat-x!important}.bg-gradient-gray-dark.btn.active,.bg-gradient-gray-dark.btn:active,.bg-gradient-gray-dark.btn:not(:disabled):not(.disabled).active,.bg-gradient-gray-dark.btn:not(:disabled):not(.disabled):active{border-color:#171a1d;color:#fff;background:#1d2124 linear-gradient(180deg,#3f4245,#1d2124) repeat-x!important}[class^=bg-].disabled{opacity:.65}a.text-muted:hover{color:#007bff!important}.link-muted{color:#5d6974}.link-muted:focus,.link-muted:hover{color:#464f58}.link-black{color:#6c757d}.link-black:focus,.link-black:hover{color:#e6e8ea}.accent-primary .btn-link,.accent-primary a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#007bff}.accent-primary .btn-link:hover,.accent-primary a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#0056b3}.accent-primary .dropdown-item.active,.accent-primary .dropdown-item:active{background:#007bff;color:#fff}.accent-primary .custom-control-input:checked~.custom-control-label:before{background:#007bff;border-color:#004a99}.accent-primary .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-primary .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-primary .custom-file-input:focus~.custom-file-label,.accent-primary .custom-select:focus,.accent-primary .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#80bdff}.accent-primary .page-item .page-link{color:#007bff}.accent-primary .page-item.active .page-link,.accent-primary .page-item.active a{background-color:#007bff;border-color:#007bff;color:#fff}.accent-primary .page-item.disabled .page-link,.accent-primary .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-primary [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-primary [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-primary [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-primary [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-secondary .btn-link,.accent-secondary a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#6c757d}.accent-secondary .btn-link:hover,.accent-secondary a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#494f54}.accent-secondary .dropdown-item.active,.accent-secondary .dropdown-item:active{background:#6c757d;color:#fff}.accent-secondary .custom-control-input:checked~.custom-control-label:before{background:#6c757d;border-color:#3d4246}.accent-secondary .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-secondary .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-secondary .custom-file-input:focus~.custom-file-label,.accent-secondary .custom-select:focus,.accent-secondary .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#afb5ba}.accent-secondary .page-item .page-link{color:#6c757d}.accent-secondary .page-item.active .page-link,.accent-secondary .page-item.active a{background-color:#6c757d;border-color:#6c757d;color:#fff}.accent-secondary .page-item.disabled .page-link,.accent-secondary .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-secondary [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-secondary [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-secondary [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-secondary [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-success .btn-link,.accent-success a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#28a745}.accent-success .btn-link:hover,.accent-success a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#19692c}.accent-success .dropdown-item.active,.accent-success .dropdown-item:active{background:#28a745;color:#fff}.accent-success .custom-control-input:checked~.custom-control-label:before{background:#28a745;border-color:#145523}.accent-success .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-success .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-success .custom-file-input:focus~.custom-file-label,.accent-success .custom-select:focus,.accent-success .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#71dd8a}.accent-success .page-item .page-link{color:#28a745}.accent-success .page-item.active .page-link,.accent-success .page-item.active a{background-color:#28a745;border-color:#28a745;color:#fff}.accent-success .page-item.disabled .page-link,.accent-success .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-success [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-success [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-success [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-success [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-info .btn-link,.accent-info a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#17a2b8}.accent-info .btn-link:hover,.accent-info a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#0f6674}.accent-info .dropdown-item.active,.accent-info .dropdown-item:active{background:#17a2b8;color:#fff}.accent-info .custom-control-input:checked~.custom-control-label:before{background:#17a2b8;border-color:#0c525d}.accent-info .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-info .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-info .custom-file-input:focus~.custom-file-label,.accent-info .custom-select:focus,.accent-info .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#63d9ec}.accent-info .page-item .page-link{color:#17a2b8}.accent-info .page-item.active .page-link,.accent-info .page-item.active a{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.accent-info .page-item.disabled .page-link,.accent-info .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-info [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-info [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-info [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-info [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-warning .btn-link,.accent-warning a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#ffc107}.accent-warning .btn-link:hover,.accent-warning a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#ba8b00}.accent-warning .dropdown-item.active,.accent-warning .dropdown-item:active{background:#ffc107;color:#1f2d3d}.accent-warning .custom-control-input:checked~.custom-control-label:before{background:#ffc107;border-color:#a07800}.accent-warning .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%231F2D3D' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-warning .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-warning .custom-file-input:focus~.custom-file-label,.accent-warning .custom-select:focus,.accent-warning .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#ffe187}.accent-warning .page-item .page-link{color:#ffc107}.accent-warning .page-item.active .page-link,.accent-warning .page-item.active a{background-color:#ffc107;border-color:#ffc107;color:#fff}.accent-warning .page-item.disabled .page-link,.accent-warning .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-warning [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-warning [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-warning [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-warning [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-danger .btn-link,.accent-danger a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#dc3545}.accent-danger .btn-link:hover,.accent-danger a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#a71d2a}.accent-danger .dropdown-item.active,.accent-danger .dropdown-item:active{background:#dc3545;color:#fff}.accent-danger .custom-control-input:checked~.custom-control-label:before{background:#dc3545;border-color:#921925}.accent-danger .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-danger .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-danger .custom-file-input:focus~.custom-file-label,.accent-danger .custom-select:focus,.accent-danger .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#efa2a9}.accent-danger .page-item .page-link{color:#dc3545}.accent-danger .page-item.active .page-link,.accent-danger .page-item.active a{background-color:#dc3545;border-color:#dc3545;color:#fff}.accent-danger .page-item.disabled .page-link,.accent-danger .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-danger [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-danger [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-danger [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-danger [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-light .btn-link,.accent-light a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#f8f9fa}.accent-light .btn-link:hover,.accent-light a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#cbd3da}.accent-light .dropdown-item.active,.accent-light .dropdown-item:active{background:#f8f9fa;color:#1f2d3d}.accent-light .custom-control-input:checked~.custom-control-label:before{background:#f8f9fa;border-color:#bdc6d0}.accent-light .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%231F2D3D' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-light .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-light .custom-file-input:focus~.custom-file-label,.accent-light .custom-select:focus,.accent-light .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#fff}.accent-light .page-item .page-link{color:#f8f9fa}.accent-light .page-item.active .page-link,.accent-light .page-item.active a{background-color:#f8f9fa;border-color:#f8f9fa;color:#fff}.accent-light .page-item.disabled .page-link,.accent-light .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-light [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-light [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-light [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-light [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-dark .btn-link,.accent-dark a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#343a40}.accent-dark .btn-link:hover,.accent-dark a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#121416}.accent-dark .dropdown-item.active,.accent-dark .dropdown-item:active{background:#343a40;color:#fff}.accent-dark .custom-control-input:checked~.custom-control-label:before{background:#343a40;border-color:#060708}.accent-dark .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-dark .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-dark .custom-file-input:focus~.custom-file-label,.accent-dark .custom-select:focus,.accent-dark .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#6d7a86}.accent-dark .page-item .page-link{color:#343a40}.accent-dark .page-item.active .page-link,.accent-dark .page-item.active a{background-color:#343a40;border-color:#343a40;color:#fff}.accent-dark .page-item.disabled .page-link,.accent-dark .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-dark [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-dark [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-dark [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-dark [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-lightblue .btn-link,.accent-lightblue a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#3c8dbc}.accent-lightblue .btn-link:hover,.accent-lightblue a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#296282}.accent-lightblue .dropdown-item.active,.accent-lightblue .dropdown-item:active{background:#3c8dbc;color:#fff}.accent-lightblue .custom-control-input:checked~.custom-control-label:before{background:#3c8dbc;border-color:#23536f}.accent-lightblue .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-lightblue .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-lightblue .custom-file-input:focus~.custom-file-label,.accent-lightblue .custom-select:focus,.accent-lightblue .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#99c5de}.accent-lightblue .page-item .page-link{color:#3c8dbc}.accent-lightblue .page-item.active .page-link,.accent-lightblue .page-item.active a{background-color:#3c8dbc;border-color:#3c8dbc;color:#fff}.accent-lightblue .page-item.disabled .page-link,.accent-lightblue .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-lightblue [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-lightblue [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-lightblue [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-lightblue [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-navy .btn-link,.accent-navy a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#001f3f}.accent-navy .btn-link:hover,.accent-navy a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#000}.accent-navy .dropdown-item.active,.accent-navy .dropdown-item:active{background:#001f3f;color:#fff}.accent-navy .custom-control-input:checked~.custom-control-label:before{background:#001f3f;border-color:#000}.accent-navy .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-navy .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-navy .custom-file-input:focus~.custom-file-label,.accent-navy .custom-select:focus,.accent-navy .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#005ebf}.accent-navy .page-item .page-link{color:#001f3f}.accent-navy .page-item.active .page-link,.accent-navy .page-item.active a{background-color:#001f3f;border-color:#001f3f;color:#fff}.accent-navy .page-item.disabled .page-link,.accent-navy .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-navy [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-navy [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-navy [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-navy [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-olive .btn-link,.accent-olive a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#3d9970}.accent-olive .btn-link:hover,.accent-olive a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#276248}.accent-olive .dropdown-item.active,.accent-olive .dropdown-item:active{background:#3d9970;color:#fff}.accent-olive .custom-control-input:checked~.custom-control-label:before{background:#3d9970;border-color:#20503b}.accent-olive .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-olive .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-olive .custom-file-input:focus~.custom-file-label,.accent-olive .custom-select:focus,.accent-olive .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#87cfaf}.accent-olive .page-item .page-link{color:#3d9970}.accent-olive .page-item.active .page-link,.accent-olive .page-item.active a{background-color:#3d9970;border-color:#3d9970;color:#fff}.accent-olive .page-item.disabled .page-link,.accent-olive .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-olive [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-olive [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-olive [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-olive [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-lime .btn-link,.accent-lime a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#01ff70}.accent-lime .btn-link:hover,.accent-lime a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#00b44e}.accent-lime .dropdown-item.active,.accent-lime .dropdown-item:active{background:#01ff70;color:#1f2d3d}.accent-lime .custom-control-input:checked~.custom-control-label:before{background:#01ff70;border-color:#009a43}.accent-lime .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%231F2D3D' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-lime .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-lime .custom-file-input:focus~.custom-file-label,.accent-lime .custom-select:focus,.accent-lime .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#81ffb8}.accent-lime .page-item .page-link{color:#01ff70}.accent-lime .page-item.active .page-link,.accent-lime .page-item.active a{background-color:#01ff70;border-color:#01ff70;color:#fff}.accent-lime .page-item.disabled .page-link,.accent-lime .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-lime [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-lime [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-lime [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-lime [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-fuchsia .btn-link,.accent-fuchsia a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#f012be}.accent-fuchsia .btn-link:hover,.accent-fuchsia a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#ab0b87}.accent-fuchsia .dropdown-item.active,.accent-fuchsia .dropdown-item:active{background:#f012be;color:#fff}.accent-fuchsia .custom-control-input:checked~.custom-control-label:before{background:#f012be;border-color:#930974}.accent-fuchsia .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-fuchsia .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-fuchsia .custom-file-input:focus~.custom-file-label,.accent-fuchsia .custom-select:focus,.accent-fuchsia .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#f88adf}.accent-fuchsia .page-item .page-link{color:#f012be}.accent-fuchsia .page-item.active .page-link,.accent-fuchsia .page-item.active a{background-color:#f012be;border-color:#f012be;color:#fff}.accent-fuchsia .page-item.disabled .page-link,.accent-fuchsia .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-fuchsia [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-fuchsia [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-fuchsia [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-fuchsia [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-maroon .btn-link,.accent-maroon a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#d81b60}.accent-maroon .btn-link:hover,.accent-maroon a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#941342}.accent-maroon .dropdown-item.active,.accent-maroon .dropdown-item:active{background:#d81b60;color:#fff}.accent-maroon .custom-control-input:checked~.custom-control-label:before{background:#d81b60;border-color:#7d1038}.accent-maroon .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-maroon .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-maroon .custom-file-input:focus~.custom-file-label,.accent-maroon .custom-select:focus,.accent-maroon .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#f083ab}.accent-maroon .page-item .page-link{color:#d81b60}.accent-maroon .page-item.active .page-link,.accent-maroon .page-item.active a{background-color:#d81b60;border-color:#d81b60;color:#fff}.accent-maroon .page-item.disabled .page-link,.accent-maroon .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-maroon [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-maroon [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-maroon [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-maroon [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-blue .btn-link,.accent-blue a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#007bff}.accent-blue .btn-link:hover,.accent-blue a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#0056b3}.accent-blue .dropdown-item.active,.accent-blue .dropdown-item:active{background:#007bff;color:#fff}.accent-blue .custom-control-input:checked~.custom-control-label:before{background:#007bff;border-color:#004a99}.accent-blue .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-blue .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-blue .custom-file-input:focus~.custom-file-label,.accent-blue .custom-select:focus,.accent-blue .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#80bdff}.accent-blue .page-item .page-link{color:#007bff}.accent-blue .page-item.active .page-link,.accent-blue .page-item.active a{background-color:#007bff;border-color:#007bff;color:#fff}.accent-blue .page-item.disabled .page-link,.accent-blue .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-blue [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-blue [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-blue [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-blue [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-indigo .btn-link,.accent-indigo a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#6610f2}.accent-indigo .btn-link:hover,.accent-indigo a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#4709ac}.accent-indigo .dropdown-item.active,.accent-indigo .dropdown-item:active{background:#6610f2;color:#fff}.accent-indigo .custom-control-input:checked~.custom-control-label:before{background:#6610f2;border-color:#3d0894}.accent-indigo .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-indigo .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-indigo .custom-file-input:focus~.custom-file-label,.accent-indigo .custom-select:focus,.accent-indigo .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#b389f9}.accent-indigo .page-item .page-link{color:#6610f2}.accent-indigo .page-item.active .page-link,.accent-indigo .page-item.active a{background-color:#6610f2;border-color:#6610f2;color:#fff}.accent-indigo .page-item.disabled .page-link,.accent-indigo .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-indigo [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-indigo [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-indigo [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-indigo [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-purple .btn-link,.accent-purple a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#6f42c1}.accent-purple .btn-link:hover,.accent-purple a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#4e2d89}.accent-purple .dropdown-item.active,.accent-purple .dropdown-item:active{background:#6f42c1;color:#fff}.accent-purple .custom-control-input:checked~.custom-control-label:before{background:#6f42c1;border-color:#432776}.accent-purple .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-purple .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-purple .custom-file-input:focus~.custom-file-label,.accent-purple .custom-select:focus,.accent-purple .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#b8a2e0}.accent-purple .page-item .page-link{color:#6f42c1}.accent-purple .page-item.active .page-link,.accent-purple .page-item.active a{background-color:#6f42c1;border-color:#6f42c1;color:#fff}.accent-purple .page-item.disabled .page-link,.accent-purple .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-purple [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-purple [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-purple [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-purple [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-pink .btn-link,.accent-pink a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#e83e8c}.accent-pink .btn-link:hover,.accent-pink a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#c21766}.accent-pink .dropdown-item.active,.accent-pink .dropdown-item:active{background:#e83e8c;color:#fff}.accent-pink .custom-control-input:checked~.custom-control-label:before{background:#e83e8c;border-color:#ac145a}.accent-pink .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-pink .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-pink .custom-file-input:focus~.custom-file-label,.accent-pink .custom-select:focus,.accent-pink .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#f6b0d0}.accent-pink .page-item .page-link{color:#e83e8c}.accent-pink .page-item.active .page-link,.accent-pink .page-item.active a{background-color:#e83e8c;border-color:#e83e8c;color:#fff}.accent-pink .page-item.disabled .page-link,.accent-pink .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-pink [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-pink [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-pink [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-pink [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-red .btn-link,.accent-red a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#dc3545}.accent-red .btn-link:hover,.accent-red a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#a71d2a}.accent-red .dropdown-item.active,.accent-red .dropdown-item:active{background:#dc3545;color:#fff}.accent-red .custom-control-input:checked~.custom-control-label:before{background:#dc3545;border-color:#921925}.accent-red .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-red .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-red .custom-file-input:focus~.custom-file-label,.accent-red .custom-select:focus,.accent-red .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#efa2a9}.accent-red .page-item .page-link{color:#dc3545}.accent-red .page-item.active .page-link,.accent-red .page-item.active a{background-color:#dc3545;border-color:#dc3545;color:#fff}.accent-red .page-item.disabled .page-link,.accent-red .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-red [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-red [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-red [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-red [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-orange .btn-link,.accent-orange a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#fd7e14}.accent-orange .btn-link:hover,.accent-orange a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#c35a02}.accent-orange .dropdown-item.active,.accent-orange .dropdown-item:active{background:#fd7e14;color:#1f2d3d}.accent-orange .custom-control-input:checked~.custom-control-label:before{background:#fd7e14;border-color:#aa4e01}.accent-orange .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%231F2D3D' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-orange .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-orange .custom-file-input:focus~.custom-file-label,.accent-orange .custom-select:focus,.accent-orange .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#fec392}.accent-orange .page-item .page-link{color:#fd7e14}.accent-orange .page-item.active .page-link,.accent-orange .page-item.active a{background-color:#fd7e14;border-color:#fd7e14;color:#fff}.accent-orange .page-item.disabled .page-link,.accent-orange .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-orange [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-orange [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-orange [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-orange [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-yellow .btn-link,.accent-yellow a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#ffc107}.accent-yellow .btn-link:hover,.accent-yellow a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#ba8b00}.accent-yellow .dropdown-item.active,.accent-yellow .dropdown-item:active{background:#ffc107;color:#1f2d3d}.accent-yellow .custom-control-input:checked~.custom-control-label:before{background:#ffc107;border-color:#a07800}.accent-yellow .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%231F2D3D' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-yellow .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-yellow .custom-file-input:focus~.custom-file-label,.accent-yellow .custom-select:focus,.accent-yellow .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#ffe187}.accent-yellow .page-item .page-link{color:#ffc107}.accent-yellow .page-item.active .page-link,.accent-yellow .page-item.active a{background-color:#ffc107;border-color:#ffc107;color:#fff}.accent-yellow .page-item.disabled .page-link,.accent-yellow .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-yellow [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-yellow [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-yellow [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-yellow [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-green .btn-link,.accent-green a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#28a745}.accent-green .btn-link:hover,.accent-green a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#19692c}.accent-green .dropdown-item.active,.accent-green .dropdown-item:active{background:#28a745;color:#fff}.accent-green .custom-control-input:checked~.custom-control-label:before{background:#28a745;border-color:#145523}.accent-green .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-green .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-green .custom-file-input:focus~.custom-file-label,.accent-green .custom-select:focus,.accent-green .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#71dd8a}.accent-green .page-item .page-link{color:#28a745}.accent-green .page-item.active .page-link,.accent-green .page-item.active a{background-color:#28a745;border-color:#28a745;color:#fff}.accent-green .page-item.disabled .page-link,.accent-green .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-green [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-green [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-green [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-green [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-teal .btn-link,.accent-teal a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#20c997}.accent-teal .btn-link:hover,.accent-teal a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#158765}.accent-teal .dropdown-item.active,.accent-teal .dropdown-item:active{background:#20c997;color:#fff}.accent-teal .custom-control-input:checked~.custom-control-label:before{background:#20c997;border-color:#127155}.accent-teal .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-teal .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-teal .custom-file-input:focus~.custom-file-label,.accent-teal .custom-select:focus,.accent-teal .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#7eeaca}.accent-teal .page-item .page-link{color:#20c997}.accent-teal .page-item.active .page-link,.accent-teal .page-item.active a{background-color:#20c997;border-color:#20c997;color:#fff}.accent-teal .page-item.disabled .page-link,.accent-teal .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-teal [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-teal [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-teal [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-teal [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-cyan .btn-link,.accent-cyan a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#17a2b8}.accent-cyan .btn-link:hover,.accent-cyan a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#0f6674}.accent-cyan .dropdown-item.active,.accent-cyan .dropdown-item:active{background:#17a2b8;color:#fff}.accent-cyan .custom-control-input:checked~.custom-control-label:before{background:#17a2b8;border-color:#0c525d}.accent-cyan .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-cyan .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-cyan .custom-file-input:focus~.custom-file-label,.accent-cyan .custom-select:focus,.accent-cyan .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#63d9ec}.accent-cyan .page-item .page-link{color:#17a2b8}.accent-cyan .page-item.active .page-link,.accent-cyan .page-item.active a{background-color:#17a2b8;border-color:#17a2b8;color:#fff}.accent-cyan .page-item.disabled .page-link,.accent-cyan .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-cyan [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-cyan [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-cyan [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-cyan [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-white .btn-link,.accent-white a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#fff}.accent-white .btn-link:hover,.accent-white a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#d9d9d9}.accent-white .dropdown-item.active,.accent-white .dropdown-item:active{background:#fff;color:#1f2d3d}.accent-white .custom-control-input:checked~.custom-control-label:before{background:#fff;border-color:#ccc}.accent-white .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%231F2D3D' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-white .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-white .custom-file-input:focus~.custom-file-label,.accent-white .custom-select:focus,.accent-white .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#fff}.accent-white .page-item .page-link{color:#fff}.accent-white .page-item.active .page-link,.accent-white .page-item.active a{background-color:#fff;border-color:#fff;color:#fff}.accent-white .page-item.disabled .page-link,.accent-white .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-white [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-white [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-white [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-white [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-gray .btn-link,.accent-gray a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#6c757d}.accent-gray .btn-link:hover,.accent-gray a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#494f54}.accent-gray .dropdown-item.active,.accent-gray .dropdown-item:active{background:#6c757d;color:#fff}.accent-gray .custom-control-input:checked~.custom-control-label:before{background:#6c757d;border-color:#3d4246}.accent-gray .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-gray .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-gray .custom-file-input:focus~.custom-file-label,.accent-gray .custom-select:focus,.accent-gray .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#afb5ba}.accent-gray .page-item .page-link{color:#6c757d}.accent-gray .page-item.active .page-link,.accent-gray .page-item.active a{background-color:#6c757d;border-color:#6c757d;color:#fff}.accent-gray .page-item.disabled .page-link,.accent-gray .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-gray [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-gray [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-gray [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-gray [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}.accent-gray-dark .btn-link,.accent-gray-dark a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn){color:#343a40}.accent-gray-dark .btn-link:hover,.accent-gray-dark a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):not(.page-link):not(.btn):hover{color:#121416}.accent-gray-dark .dropdown-item.active,.accent-gray-dark .dropdown-item:active{background:#343a40;color:#fff}.accent-gray-dark .custom-control-input:checked~.custom-control-label:before{background:#343a40;border-color:#060708}.accent-gray-dark .custom-control-input:checked~.custom-control-label:after{background-image:url("data:image/svg+xml;charset=utf8,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 8 8'%3E%3Cpath fill='%23ffffff' d='M6.564.75l-3.59 3.612-1.538-1.55L0 4.26 2.974 7.25 8 2.193z'/%3E%3C/svg%3E")}.accent-gray-dark .custom-control-input:focus:not(:checked)~.custom-control-label:before,.accent-gray-dark .custom-file-input:focus~.custom-file-label,.accent-gray-dark .custom-select:focus,.accent-gray-dark .form-control:focus:not(.is-invalid):not(.is-warning):not(.is-valid){border-color:#6d7a86}.accent-gray-dark .page-item .page-link{color:#343a40}.accent-gray-dark .page-item.active .page-link,.accent-gray-dark .page-item.active a{background-color:#343a40;border-color:#343a40;color:#fff}.accent-gray-dark .page-item.disabled .page-link,.accent-gray-dark .page-item.disabled a{background-color:#fff;border-color:#dee2e6;color:#6c757d}.accent-gray-dark [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#c2c7d0}.accent-gray-dark [class*=sidebar-dark-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#fff}.accent-gray-dark [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link){color:#343a40}.accent-gray-dark [class*=sidebar-light-] .sidebar a:not(.dropdown-item):not(.btn-app):not(.nav-link):not(.brand-link):hover{color:#212529}[class*=accent-] a.btn-info,[class*=accent-] a.btn-primary,[class*=accent-] a.btn-secondary,[class*=accent-] a.btn-success{color:#fff}[class*=accent-] a.btn-warning{color:#1f2d3d}[class*=accent-] a.btn-danger{color:#fff}[class*=accent-] a.btn-light{color:#1f2d3d}[class*=accent-] a.btn-dark{color:#fff} \ No newline at end of file diff --git a/frontend/public/js/dashboard.js b/frontend/public/js/dashboard.js new file mode 100644 index 0000000000..0ee5912bac --- /dev/null +++ b/frontend/public/js/dashboard.js @@ -0,0 +1,3 @@ +/*! For license information please see dashboard.js.LICENSE.txt */ +(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{157:function(t,e,s){s(215),t.exports=s(216)},159:function(t,e,s){var n={"./af":11,"./af.js":11,"./ar":12,"./ar-dz":13,"./ar-dz.js":13,"./ar-kw":14,"./ar-kw.js":14,"./ar-ly":15,"./ar-ly.js":15,"./ar-ma":16,"./ar-ma.js":16,"./ar-sa":17,"./ar-sa.js":17,"./ar-tn":18,"./ar-tn.js":18,"./ar.js":12,"./az":19,"./az.js":19,"./be":20,"./be.js":20,"./bg":21,"./bg.js":21,"./bm":22,"./bm.js":22,"./bn":23,"./bn.js":23,"./bo":24,"./bo.js":24,"./br":25,"./br.js":25,"./bs":26,"./bs.js":26,"./ca":27,"./ca.js":27,"./cs":28,"./cs.js":28,"./cv":29,"./cv.js":29,"./cy":30,"./cy.js":30,"./da":31,"./da.js":31,"./de":32,"./de-at":33,"./de-at.js":33,"./de-ch":34,"./de-ch.js":34,"./de.js":32,"./dv":35,"./dv.js":35,"./el":36,"./el.js":36,"./en-au":37,"./en-au.js":37,"./en-ca":38,"./en-ca.js":38,"./en-gb":39,"./en-gb.js":39,"./en-ie":40,"./en-ie.js":40,"./en-il":41,"./en-il.js":41,"./en-in":42,"./en-in.js":42,"./en-nz":43,"./en-nz.js":43,"./en-sg":44,"./en-sg.js":44,"./eo":45,"./eo.js":45,"./es":46,"./es-do":47,"./es-do.js":47,"./es-us":48,"./es-us.js":48,"./es.js":46,"./et":49,"./et.js":49,"./eu":50,"./eu.js":50,"./fa":51,"./fa.js":51,"./fi":52,"./fi.js":52,"./fil":53,"./fil.js":53,"./fo":54,"./fo.js":54,"./fr":55,"./fr-ca":56,"./fr-ca.js":56,"./fr-ch":57,"./fr-ch.js":57,"./fr.js":55,"./fy":58,"./fy.js":58,"./ga":59,"./ga.js":59,"./gd":60,"./gd.js":60,"./gl":61,"./gl.js":61,"./gom-deva":62,"./gom-deva.js":62,"./gom-latn":63,"./gom-latn.js":63,"./gu":64,"./gu.js":64,"./he":65,"./he.js":65,"./hi":66,"./hi.js":66,"./hr":67,"./hr.js":67,"./hu":68,"./hu.js":68,"./hy-am":69,"./hy-am.js":69,"./id":70,"./id.js":70,"./is":71,"./is.js":71,"./it":72,"./it-ch":73,"./it-ch.js":73,"./it.js":72,"./ja":74,"./ja.js":74,"./jv":75,"./jv.js":75,"./ka":76,"./ka.js":76,"./kk":77,"./kk.js":77,"./km":78,"./km.js":78,"./kn":79,"./kn.js":79,"./ko":80,"./ko.js":80,"./ku":81,"./ku.js":81,"./ky":82,"./ky.js":82,"./lb":83,"./lb.js":83,"./lo":84,"./lo.js":84,"./lt":85,"./lt.js":85,"./lv":86,"./lv.js":86,"./me":87,"./me.js":87,"./mi":88,"./mi.js":88,"./mk":89,"./mk.js":89,"./ml":90,"./ml.js":90,"./mn":91,"./mn.js":91,"./mr":92,"./mr.js":92,"./ms":93,"./ms-my":94,"./ms-my.js":94,"./ms.js":93,"./mt":95,"./mt.js":95,"./my":96,"./my.js":96,"./nb":97,"./nb.js":97,"./ne":98,"./ne.js":98,"./nl":99,"./nl-be":100,"./nl-be.js":100,"./nl.js":99,"./nn":101,"./nn.js":101,"./oc-lnc":102,"./oc-lnc.js":102,"./pa-in":103,"./pa-in.js":103,"./pl":104,"./pl.js":104,"./pt":105,"./pt-br":106,"./pt-br.js":106,"./pt.js":105,"./ro":107,"./ro.js":107,"./ru":108,"./ru.js":108,"./sd":109,"./sd.js":109,"./se":110,"./se.js":110,"./si":111,"./si.js":111,"./sk":112,"./sk.js":112,"./sl":113,"./sl.js":113,"./sq":114,"./sq.js":114,"./sr":115,"./sr-cyrl":116,"./sr-cyrl.js":116,"./sr.js":115,"./ss":117,"./ss.js":117,"./sv":118,"./sv.js":118,"./sw":119,"./sw.js":119,"./ta":120,"./ta.js":120,"./te":121,"./te.js":121,"./tet":122,"./tet.js":122,"./tg":123,"./tg.js":123,"./th":124,"./th.js":124,"./tl-ph":125,"./tl-ph.js":125,"./tlh":126,"./tlh.js":126,"./tr":127,"./tr.js":127,"./tzl":128,"./tzl.js":128,"./tzm":129,"./tzm-latn":130,"./tzm-latn.js":130,"./tzm.js":129,"./ug-cn":131,"./ug-cn.js":131,"./uk":132,"./uk.js":132,"./ur":133,"./ur.js":133,"./uz":134,"./uz-latn":135,"./uz-latn.js":135,"./uz.js":134,"./vi":136,"./vi.js":136,"./x-pseudo":137,"./x-pseudo.js":137,"./yo":138,"./yo.js":138,"./zh-cn":139,"./zh-cn.js":139,"./zh-hk":140,"./zh-hk.js":140,"./zh-mo":141,"./zh-mo.js":141,"./zh-tw":142,"./zh-tw.js":142};function a(t){var e=i(t);return s(e)}function i(t){if(!s.o(n,t)){var e=new Error("Cannot find module '"+t+"'");throw e.code="MODULE_NOT_FOUND",e}return n[t]}a.keys=function(){return Object.keys(n)},a.resolve=i,t.exports=a,a.id=159},160:function(t,e,s){"use strict";var n=s(7);s.n(n).a},161:function(t,e,s){(t.exports=s(162)(!1)).push([t.i,"\n.main-account-chart[data-v-8f6c5148] {\n}\n\n",""])},165:function(t,e,s){"use strict";s.r(e);var n=s(9),a=s.n(n),i=s(155),o=s(10);window.$=window.jQuery=s(4),window.axios=s(168),window.axios.defaults.headers.common["X-Requested-With"]="XMLHttpRequest";var r=document.head.querySelector('meta[name="csrf-token"]');r?window.axios.defaults.headers.common["X-CSRF-TOKEN"]=r.content:console.error("CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token");var l=document.head.querySelector('meta[name="locale"]');window.localeValue=l?l.content:"en_US",s(185),s(153),s(188),s(189),window.vuei18n=i.a,window.uiv=o,a.a.use(vuei18n),a.a.use(o),window.Vue=a.a},188:function(t,e,s){var n,a,i,o;function r(t){return(r="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}o=function(t){"use strict";var e=function(t){var e="ControlSidebar",s="lte.controlsidebar",n=t.fn[e],a={COLLAPSED:"collapsed.lte.controlsidebar",EXPANDED:"expanded.lte.controlsidebar"},i=".control-sidebar",o=".control-sidebar-content",r='[data-widget="control-sidebar"]',l=".main-header",c=".main-footer",d="control-sidebar-animate",u="control-sidebar-open",h="control-sidebar-slide-open",f="layout-fixed",_="layout-navbar-fixed",p="layout-sm-navbar-fixed",g="layout-md-navbar-fixed",m="layout-lg-navbar-fixed",v="layout-xl-navbar-fixed",b="layout-footer-fixed",y="layout-sm-footer-fixed",C="layout-md-footer-fixed",w="layout-lg-footer-fixed",j="layout-xl-footer-fixed",x={controlsidebarSlide:!0,scrollbarTheme:"os-theme-light",scrollbarAutoHide:"l"},E=function(){function e(t,e){this._element=t,this._config=e,this._init()}var n=e.prototype;return n.collapse=function(){this._config.controlsidebarSlide?(t("html").addClass(d),t("body").removeClass(h).delay(300).queue((function(){t(i).hide(),t("html").removeClass(d),t(this).dequeue()}))):t("body").removeClass(u);var e=t.Event(a.COLLAPSED);t(this._element).trigger(e)},n.show=function(){this._config.controlsidebarSlide?(t("html").addClass(d),t(i).show().delay(10).queue((function(){t("body").addClass(h).delay(300).queue((function(){t("html").removeClass(d),t(this).dequeue()})),t(this).dequeue()}))):t("body").addClass(u);var e=t.Event(a.EXPANDED);t(this._element).trigger(e)},n.toggle=function(){t("body").hasClass(u)||t("body").hasClass(h)?this.collapse():this.show()},n._init=function(){var e=this;this._fixHeight(),this._fixScrollHeight(),t(window).resize((function(){e._fixHeight(),e._fixScrollHeight()})),t(window).scroll((function(){(t("body").hasClass(u)||t("body").hasClass(h))&&e._fixScrollHeight()}))},n._fixScrollHeight=function(){var e={scroll:t(document).height(),window:t(window).height(),header:t(l).outerHeight(),footer:t(c).outerHeight()},s=Math.abs(e.window+t(window).scrollTop()-e.scroll),n=t(window).scrollTop(),a=!1,r=!1;t("body").hasClass(f)&&((t("body").hasClass(_)||t("body").hasClass(p)||t("body").hasClass(g)||t("body").hasClass(m)||t("body").hasClass(v))&&"fixed"===t(l).css("position")&&(a=!0),(t("body").hasClass(b)||t("body").hasClass(y)||t("body").hasClass(C)||t("body").hasClass(w)||t("body").hasClass(j))&&"fixed"===t(c).css("position")&&(r=!0),0===n&&0===s?(t(i).css("bottom",e.footer),t(i).css("top",e.header),t(i+", "+i+" "+o).css("height",e.window-(e.header+e.footer))):s<=e.footer?!1===r?(t(i).css("bottom",e.footer-s),t(i+", "+i+" "+o).css("height",e.window-(e.footer-s))):t(i).css("bottom",e.footer):n<=e.header?!1===a?(t(i).css("top",e.header-n),t(i+", "+i+" "+o).css("height",e.window-(e.header-n))):t(i).css("top",e.header):!1===a?(t(i).css("top",0),t(i+", "+i+" "+o).css("height",e.window)):t(i).css("top",e.header))},n._fixHeight=function(){var e=t(window).height(),s=t(l).outerHeight(),n=t(c).outerHeight();if(t("body").hasClass(f)){var a=e-s;(t("body").hasClass(b)||t("body").hasClass(y)||t("body").hasClass(C)||t("body").hasClass(w)||t("body").hasClass(j))&&"fixed"===t(c).css("position")&&(a=e-s-n),t(i+" "+o).css("height",a),void 0!==t.fn.overlayScrollbars&&t(i+" "+o).overlayScrollbars({className:this._config.scrollbarTheme,sizeAutoCapable:!0,scrollbars:{autoHide:this._config.scrollbarAutoHide,clickScrolling:!0}})}},e._jQueryInterface=function(n){return this.each((function(){var a=t(this).data(s),i=t.extend({},x,t(this).data());if(a||(a=new e(this,i),t(this).data(s,a)),"undefined"===a[n])throw new Error(n+" is not a function");a[n]()}))},e}();return t(document).on("click",r,(function(e){e.preventDefault(),E._jQueryInterface.call(t(this),"toggle")})),t.fn[e]=E._jQueryInterface,t.fn[e].Constructor=E,t.fn[e].noConflict=function(){return t.fn[e]=n,E._jQueryInterface},E}(jQuery),s=function(t){var e="Layout",s=t.fn[e],n=".main-header",a=".main-sidebar",i=".main-sidebar .sidebar",o=".content-wrapper",r=".control-sidebar-content",l='[data-widget="control-sidebar"]',c=".main-footer",d='[data-widget="pushmenu"]',u=".login-box",h=".register-box",f="sidebar-focused",_="layout-fixed",p="control-sidebar-slide-open",g="control-sidebar-open",m={scrollbarTheme:"os-theme-light",scrollbarAutoHide:"l",panelAutoHeight:!0,loginRegisterAutoHeight:!0},v=function(){function e(t,e){this._config=e,this._element=t,this._init()}var s=e.prototype;return s.fixLayoutHeight=function(e){void 0===e&&(e=null);var s=0;(t("body").hasClass(p)||t("body").hasClass(g)||"control_sidebar"==e)&&(s=t(r).height());var a={window:t(window).height(),header:0!==t(n).length?t(n).outerHeight():0,footer:0!==t(c).length?t(c).outerHeight():0,sidebar:0!==t(i).length?t(i).height():0,control_sidebar:s},l=this._max(a),d=this._config.panelAutoHeight;!0===d&&(d=0),!1!==d&&(l==a.control_sidebar?t(o).css("min-height",l+d):l==a.window?t(o).css("min-height",l+d-a.header-a.footer):t(o).css("min-height",l+d-a.header),this._isFooterFixed()&&t(o).css("min-height",parseFloat(t(o).css("min-height"))+a.footer)),t("body").hasClass(_)&&(!1!==d&&t(o).css("min-height",l+d-a.header-a.footer),void 0!==t.fn.overlayScrollbars&&t(i).overlayScrollbars({className:this._config.scrollbarTheme,sizeAutoCapable:!0,scrollbars:{autoHide:this._config.scrollbarAutoHide,clickScrolling:!0}}))},s.fixLoginRegisterHeight=function(){if(0===t(u+", "+h).length)t("body, html").css("height","auto");else if(0!==t(u+", "+h).length){var e=t(u+", "+h).height();t("body").css("min-height")!==e&&t("body").css("min-height",e)}},s._init=function(){var e=this;this.fixLayoutHeight(),!0===this._config.loginRegisterAutoHeight?this.fixLoginRegisterHeight():Number.isInteger(this._config.loginRegisterAutoHeight)&&setInterval(this.fixLoginRegisterHeight,this._config.loginRegisterAutoHeight),t(i).on("collapsed.lte.treeview expanded.lte.treeview",(function(){e.fixLayoutHeight()})),t(d).on("collapsed.lte.pushmenu shown.lte.pushmenu",(function(){e.fixLayoutHeight()})),t(l).on("collapsed.lte.controlsidebar",(function(){e.fixLayoutHeight()})).on("expanded.lte.controlsidebar",(function(){e.fixLayoutHeight("control_sidebar")})),t(window).resize((function(){e.fixLayoutHeight()})),setTimeout((function(){t("body.hold-transition").removeClass("hold-transition")}),50)},s._max=function(t){var e=0;return Object.keys(t).forEach((function(s){t[s]>e&&(e=t[s])})),e},s._isFooterFixed=function(){return"fixed"===t(".main-footer").css("position")},e._jQueryInterface=function(s){return void 0===s&&(s=""),this.each((function(){var n=t(this).data("lte.layout"),a=t.extend({},m,t(this).data());n||(n=new e(t(this),a),t(this).data("lte.layout",n)),"init"===s||""===s?n._init():"fixLayoutHeight"!==s&&"fixLoginRegisterHeight"!==s||n[s]()}))},e}();return t(window).on("load",(function(){v._jQueryInterface.call(t("body"))})),t(i+" a").on("focusin",(function(){t(a).addClass(f)})),t(i+" a").on("focusout",(function(){t(a).removeClass(f)})),t.fn[e]=v._jQueryInterface,t.fn[e].Constructor=v,t.fn[e].noConflict=function(){return t.fn[e]=s,v._jQueryInterface},v}(jQuery),n=function(t){var e="PushMenu",s=".lte.pushmenu",n=t.fn[e],a={COLLAPSED:"collapsed"+s,SHOWN:"shown"+s},i={autoCollapseSize:992,enableRemember:!1,noTransitionAfterReload:!0},o='[data-widget="pushmenu"]',r="body",l="#sidebar-overlay",c=".wrapper",d="sidebar-collapse",u="sidebar-open",h="sidebar-closed",f=function(){function e(e,s){this._element=e,this._options=t.extend({},i,s),t(l).length||this._addOverlay(),this._init()}var n=e.prototype;return n.expand=function(){this._options.autoCollapseSize&&t(window).width()<=this._options.autoCollapseSize&&t(r).addClass(u),t(r).removeClass(d).removeClass(h),this._options.enableRemember&&localStorage.setItem("remember"+s,u);var e=t.Event(a.SHOWN);t(this._element).trigger(e)},n.collapse=function(){this._options.autoCollapseSize&&t(window).width()<=this._options.autoCollapseSize&&t(r).removeClass(u).addClass(h),t(r).addClass(d),this._options.enableRemember&&localStorage.setItem("remember"+s,d);var e=t.Event(a.COLLAPSED);t(this._element).trigger(e)},n.toggle=function(){t(r).hasClass(d)?this.expand():this.collapse()},n.autoCollapse=function(e){void 0===e&&(e=!1),this._options.autoCollapseSize&&(t(window).width()<=this._options.autoCollapseSize?t(r).hasClass(u)||this.collapse():1==e&&(t(r).hasClass(u)?t(r).removeClass(u):t(r).hasClass(h)&&this.expand()))},n.remember=function(){this._options.enableRemember&&(localStorage.getItem("remember"+s)==d?this._options.noTransitionAfterReload?t("body").addClass("hold-transition").addClass(d).delay(50).queue((function(){t(this).removeClass("hold-transition"),t(this).dequeue()})):t("body").addClass(d):this._options.noTransitionAfterReload?t("body").addClass("hold-transition").removeClass(d).delay(50).queue((function(){t(this).removeClass("hold-transition"),t(this).dequeue()})):t("body").removeClass(d))},n._init=function(){var e=this;this.remember(),this.autoCollapse(),t(window).resize((function(){e.autoCollapse(!0)}))},n._addOverlay=function(){var e=this,s=t("
",{id:"sidebar-overlay"});s.on("click",(function(){e.collapse()})),t(c).append(s)},e._jQueryInterface=function(s){return this.each((function(){var n=t(this).data("lte.pushmenu"),a=t.extend({},i,t(this).data());n||(n=new e(this,a),t(this).data("lte.pushmenu",n)),"string"==typeof s&&s.match(/collapse|expand|toggle/)&&n[s]()}))},e}();return t(document).on("click",o,(function(e){e.preventDefault();var s=e.currentTarget;"pushmenu"!==t(s).data("widget")&&(s=t(s).closest(o)),f._jQueryInterface.call(t(s),"toggle")})),t(window).on("load",(function(){f._jQueryInterface.call(t(o))})),t.fn[e]=f._jQueryInterface,t.fn[e].Constructor=f,t.fn[e].noConflict=function(){return t.fn[e]=n,f._jQueryInterface},f}(jQuery),a=function(t){var e="Treeview",s=t.fn[e],n={SELECTED:"selected.lte.treeview",EXPANDED:"expanded.lte.treeview",COLLAPSED:"collapsed.lte.treeview",LOAD_DATA_API:"load.lte.treeview"},a=".nav-item",i=".nav-treeview",o=".menu-open",r='[data-widget="treeview"]',l="menu-open",c="sidebar-collapse",d={trigger:r+" .nav-link",animationSpeed:300,accordion:!0,expandSidebar:!1,sidebarButtonSelector:'[data-widget="pushmenu"]'},u=function(){function e(t,e){this._config=e,this._element=t}var s=e.prototype;return s.init=function(){this._setupListeners()},s.expand=function(e,s){var a=this,r=t.Event(n.EXPANDED);if(this._config.accordion){var c=s.siblings(o).first(),d=c.find(i).first();this.collapse(d,c)}e.stop().slideDown(this._config.animationSpeed,(function(){s.addClass(l),t(a._element).trigger(r)})),this._config.expandSidebar&&this._expandSidebar()},s.collapse=function(e,s){var a=this,r=t.Event(n.COLLAPSED);e.stop().slideUp(this._config.animationSpeed,(function(){s.removeClass(l),t(a._element).trigger(r),e.find(o+" > "+i).slideUp(),e.find(o).removeClass(l)}))},s.toggle=function(e){var s=t(e.currentTarget),n=s.parent(),o=n.find("> "+i);if(o.is(i)||(n.is(a)||(o=n.parent().find("> "+i)),o.is(i))){e.preventDefault();var r=s.parents(a).first();r.hasClass(l)?this.collapse(t(o),r):this.expand(t(o),r)}},s._setupListeners=function(){var e=this;t(document).on("click",this._config.trigger,(function(t){e.toggle(t)}))},s._expandSidebar=function(){t("body").hasClass(c)&&t(this._config.sidebarButtonSelector).PushMenu("expand")},e._jQueryInterface=function(s){return this.each((function(){var n=t(this).data("lte.treeview"),a=t.extend({},d,t(this).data());n||(n=new e(t(this),a),t(this).data("lte.treeview",n)),"init"===s&&n[s]()}))},e}();return t(window).on(n.LOAD_DATA_API,(function(){t(r).each((function(){u._jQueryInterface.call(t(this),"init")}))})),t.fn[e]=u._jQueryInterface,t.fn[e].Constructor=u,t.fn[e].noConflict=function(){return t.fn[e]=s,u._jQueryInterface},u}(jQuery),i=function(t){var e="DirectChat",s=t.fn[e],n="toggled{EVENT_KEY}",a='[data-widget="chat-pane-toggle"]',i=".direct-chat",o="direct-chat-contacts-open",r=function(){function e(t,e){this._element=t}return e.prototype.toggle=function(){t(this._element).parents(i).first().toggleClass(o);var e=t.Event(n);t(this._element).trigger(e)},e._jQueryInterface=function(s){return this.each((function(){var n=t(this).data("lte.directchat");n||(n=new e(t(this)),t(this).data("lte.directchat",n)),n[s]()}))},e}();return t(document).on("click",a,(function(e){e&&e.preventDefault(),r._jQueryInterface.call(t(this),"toggle")})),t.fn[e]=r._jQueryInterface,t.fn[e].Constructor=r,t.fn[e].noConflict=function(){return t.fn[e]=s,r._jQueryInterface},r}(jQuery),o=function(t){var e="TodoList",s=t.fn[e],n='[data-widget="todo-list"]',a="done",i={onCheck:function(t){return t},onUnCheck:function(t){return t}},o=function(){function e(t,e){this._config=e,this._element=t,this._init()}var s=e.prototype;return s.toggle=function(e){e.parents("li").toggleClass(a),t(e).prop("checked")?this.check(e):this.unCheck(t(e))},s.check=function(t){this._config.onCheck.call(t)},s.unCheck=function(t){this._config.onUnCheck.call(t)},s._init=function(){var e=this;t(n).find("input:checkbox:checked").parents("li").toggleClass(a),t(n).on("change","input:checkbox",(function(s){e.toggle(t(s.target))}))},e._jQueryInterface=function(s){return this.each((function(){var n=t(this).data("lte.todolist"),a=t.extend({},i,t(this).data());n||(n=new e(t(this),a),t(this).data("lte.todolist",n)),"init"===s&&n[s]()}))},e}();return t(window).on("load",(function(){o._jQueryInterface.call(t(n))})),t.fn[e]=o._jQueryInterface,t.fn[e].Constructor=o,t.fn[e].noConflict=function(){return t.fn[e]=s,o._jQueryInterface},o}(jQuery),l=function(t){var e="CardWidget",s=".lte.cardwidget",n=t.fn[e],a={EXPANDED:"expanded"+s,COLLAPSED:"collapsed"+s,MAXIMIZED:"maximized"+s,MINIMIZED:"minimized"+s,REMOVED:"removed"+s},i="card",o="collapsed-card",l="collapsing-card",c="expanding-card",d="was-collapsed",u="maximized-card",h={DATA_REMOVE:'[data-card-widget="remove"]',DATA_COLLAPSE:'[data-card-widget="collapse"]',DATA_MAXIMIZE:'[data-card-widget="maximize"]',CARD:"."+i,CARD_HEADER:".card-header",CARD_BODY:".card-body",CARD_FOOTER:".card-footer",COLLAPSED:"."+o},f={animationSpeed:"normal",collapseTrigger:h.DATA_COLLAPSE,removeTrigger:h.DATA_REMOVE,maximizeTrigger:h.DATA_MAXIMIZE,collapseIcon:"fa-minus",expandIcon:"fa-plus",maximizeIcon:"fa-expand",minimizeIcon:"fa-compress"},_=function(){function e(e,s){this._element=e,this._parent=e.parents(h.CARD).first(),e.hasClass(i)&&(this._parent=e),this._settings=t.extend({},f,s)}var s=e.prototype;return s.collapse=function(){var e=this;this._parent.addClass(l).children(h.CARD_BODY+", "+h.CARD_FOOTER).slideUp(this._settings.animationSpeed,(function(){e._parent.addClass(o).removeClass(l)})),this._parent.find("> "+h.CARD_HEADER+" "+this._settings.collapseTrigger+" ."+this._settings.collapseIcon).addClass(this._settings.expandIcon).removeClass(this._settings.collapseIcon);var s=t.Event(a.COLLAPSED);this._element.trigger(s,this._parent)},s.expand=function(){var e=this;this._parent.addClass(c).children(h.CARD_BODY+", "+h.CARD_FOOTER).slideDown(this._settings.animationSpeed,(function(){e._parent.removeClass(o).removeClass(c)})),this._parent.find("> "+h.CARD_HEADER+" "+this._settings.collapseTrigger+" ."+this._settings.expandIcon).addClass(this._settings.collapseIcon).removeClass(this._settings.expandIcon);var s=t.Event(a.EXPANDED);this._element.trigger(s,this._parent)},s.remove=function(){this._parent.slideUp();var e=t.Event(a.REMOVED);this._element.trigger(e,this._parent)},s.toggle=function(){this._parent.hasClass(o)?this.expand():this.collapse()},s.maximize=function(){this._parent.find(this._settings.maximizeTrigger+" ."+this._settings.maximizeIcon).addClass(this._settings.minimizeIcon).removeClass(this._settings.maximizeIcon),this._parent.css({height:this._parent.height(),width:this._parent.width(),transition:"all .15s"}).delay(150).queue((function(){t(this).addClass(u),t("html").addClass(u),t(this).hasClass(o)&&t(this).addClass(d),t(this).dequeue()}));var e=t.Event(a.MAXIMIZED);this._element.trigger(e,this._parent)},s.minimize=function(){this._parent.find(this._settings.maximizeTrigger+" ."+this._settings.minimizeIcon).addClass(this._settings.maximizeIcon).removeClass(this._settings.minimizeIcon),this._parent.css("cssText","height:"+this._parent[0].style.height+" !important;width:"+this._parent[0].style.width+" !important; transition: all .15s;").delay(10).queue((function(){t(this).removeClass(u),t("html").removeClass(u),t(this).css({height:"inherit",width:"inherit"}),t(this).hasClass(d)&&t(this).removeClass(d),t(this).dequeue()}));var e=t.Event(a.MINIMIZED);this._element.trigger(e,this._parent)},s.toggleMaximize=function(){this._parent.hasClass(u)?this.minimize():this.maximize()},s._init=function(e){var s=this;this._parent=e,t(this).find(this._settings.collapseTrigger).click((function(){s.toggle()})),t(this).find(this._settings.maximizeTrigger).click((function(){s.toggleMaximize()})),t(this).find(this._settings.removeTrigger).click((function(){s.remove()}))},e._jQueryInterface=function(s){var n=t(this).data("lte.cardwidget"),a=t.extend({},f,t(this).data());n||(n=new e(t(this),a),t(this).data("lte.cardwidget","string"==typeof s?n:s)),"string"==typeof s&&s.match(/collapse|expand|remove|toggle|maximize|minimize|toggleMaximize/)?n[s]():"object"===r(s)&&n._init(t(this))},e}();return t(document).on("click",h.DATA_COLLAPSE,(function(e){e&&e.preventDefault(),_._jQueryInterface.call(t(this),"toggle")})),t(document).on("click",h.DATA_REMOVE,(function(e){e&&e.preventDefault(),_._jQueryInterface.call(t(this),"remove")})),t(document).on("click",h.DATA_MAXIMIZE,(function(e){e&&e.preventDefault(),_._jQueryInterface.call(t(this),"toggleMaximize")})),t.fn[e]=_._jQueryInterface,t.fn[e].Constructor=_,t.fn[e].noConflict=function(){return t.fn[e]=n,_._jQueryInterface},_}(jQuery),c=function(t){var e="CardRefresh",s=t.fn[e],n={LOADED:"loaded.lte.cardrefresh",OVERLAY_ADDED:"overlay.added.lte.cardrefresh",OVERLAY_REMOVED:"overlay.removed.lte.cardrefresh"},a="card",i={CARD:"."+a,DATA_REFRESH:'[data-card-widget="card-refresh"]'},o={source:"",sourceSelector:"",params:{},trigger:i.DATA_REFRESH,content:".card-body",loadInContent:!0,loadOnInit:!0,responseType:"",overlayTemplate:'
',onLoadStart:function(){},onLoadDone:function(t){return t}},r=function(){function e(e,s){if(this._element=e,this._parent=e.parents(i.CARD).first(),this._settings=t.extend({},o,s),this._overlay=t(this._settings.overlayTemplate),e.hasClass(a)&&(this._parent=e),""===this._settings.source)throw new Error("Source url was not defined. Please specify a url in your CardRefresh source option.")}var s=e.prototype;return s.load=function(){this._addOverlay(),this._settings.onLoadStart.call(t(this)),t.get(this._settings.source,this._settings.params,function(e){this._settings.loadInContent&&(""!=this._settings.sourceSelector&&(e=t(e).find(this._settings.sourceSelector).html()),this._parent.find(this._settings.content).html(e)),this._settings.onLoadDone.call(t(this),e),this._removeOverlay()}.bind(this),""!==this._settings.responseType&&this._settings.responseType);var e=t.Event(n.LOADED);t(this._element).trigger(e)},s._addOverlay=function(){this._parent.append(this._overlay);var e=t.Event(n.OVERLAY_ADDED);t(this._element).trigger(e)},s._removeOverlay=function(){this._parent.find(this._overlay).remove();var e=t.Event(n.OVERLAY_REMOVED);t(this._element).trigger(e)},s._init=function(e){var s=this;t(this).find(this._settings.trigger).on("click",(function(){s.load()})),this._settings.loadOnInit&&this.load()},e._jQueryInterface=function(s){var n=t(this).data("lte.cardrefresh"),a=t.extend({},o,t(this).data());n||(n=new e(t(this),a),t(this).data("lte.cardrefresh","string"==typeof s?n:s)),"string"==typeof s&&s.match(/load/)?n[s]():n._init(t(this))},e}();return t(document).on("click",i.DATA_REFRESH,(function(e){e&&e.preventDefault(),r._jQueryInterface.call(t(this),"load")})),t(document).ready((function(){t(i.DATA_REFRESH).each((function(){r._jQueryInterface.call(t(this))}))})),t.fn[e]=r._jQueryInterface,t.fn[e].Constructor=r,t.fn[e].noConflict=function(){return t.fn[e]=s,r._jQueryInterface},r}(jQuery),d=function(t){var e="Dropdown",s=t.fn[e],n=".navbar",a=".dropdown-menu",i=".dropdown-menu.show",o='[data-toggle="dropdown"]',r="dropdown-menu-right",l={},c=function(){function e(t,e){this._config=e,this._element=t}var s=e.prototype;return s.toggleSubmenu=function(){this._element.siblings().show().toggleClass("show"),this._element.next().hasClass("show")||this._element.parents(".dropdown-menu").first().find(".show").removeClass("show").hide(),this._element.parents("li.nav-item.dropdown.show").on("hidden.bs.dropdown",(function(e){t(".dropdown-submenu .show").removeClass("show").hide()}))},s.fixPosition=function(){var e=t(i);if(0!==e.length){e.hasClass(r)?(e.css("left","inherit"),e.css("right",0)):(e.css("left",0),e.css("right","inherit"));var s=e.offset(),n=e.width(),a=t(window).width()-s.left;s.left<0?(e.css("left","inherit"),e.css("right",s.left-5)):a');e.data("autohide",this._config.autohide),e.data("animation",this._config.fade),this._config.class&&e.addClass(this._config.class),this._config.delay&&500!=this._config.delay&&e.data("delay",this._config.delay);var s=t('
');if(null!=this._config.image){var a=t("").addClass("rounded mr-2").attr("src",this._config.image).attr("alt",this._config.imageAlt);null!=this._config.imageHeight&&a.height(this._config.imageHeight).width("auto"),s.append(a)}if(null!=this._config.icon&&s.append(t("").addClass("mr-2").addClass(this._config.icon)),null!=this._config.title&&s.append(t("").addClass("mr-auto").html(this._config.title)),null!=this._config.subtitle&&s.append(t("").html(this._config.subtitle)),1==this._config.close){var i=t(' -
-
- - - - - - -{% endblock %} diff --git a/resources/views/v1/import/file/new.twig b/resources/views/v1/import/file/new.twig deleted file mode 100644 index 758c9a6a65..0000000000 --- a/resources/views/v1/import/file/new.twig +++ /dev/null @@ -1,60 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
-
-
-

{{ trans('import.job_config_file_upload_title') }}

-
-
-

- {{ trans('import.job_config_file_upload_text') }} -

-

- {{ trans('import.final_csv_import')|raw }} -

-
-
- -
-
- -
- - - -
-
-
-
-

{{ trans('import.job_config_input') }}

-
-
- {{ ExpandedForm.file('import_file', {helpText: trans('import.job_config_file_upload_help')}) }} - {{ ExpandedForm.file('configuration_file', {helpText: trans('import.job_config_file_upload_config_help')|raw}) }} - {{ ExpandedForm.select('import_file_type', data.file_types, data.default_type, {'helpText' : trans('import.job_config_file_upload_type_help')}) }} -
-
-
-
-
-
-
-
- -
-
-
-
-
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/file/roles.twig b/resources/views/v1/import/file/roles.twig deleted file mode 100644 index a983dc1b35..0000000000 --- a/resources/views/v1/import/file/roles.twig +++ /dev/null @@ -1,100 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render(Route.getCurrentRoute.getName, importJob) }} -{% endblock %} - -{% block content %} - -
-
-
-
-

{{ trans('import.job_config_roles_title') }}

-
-
-

- {{ trans('import.job_config_roles_text') }} -

-
-
- -
-
-
- - -
-
-
-
-

{{ trans('import.job_config_input') }}

-
-
- - - - - - - - - - {% for i in 0..(data.total -1) %} - - - - - - - - {% endfor %} - - -
{{ trans('import.job_config_roles_column_name') }}{{ trans('import.job_config_roles_column_example') }}{{ trans('import.job_config_roles_column_role') }}{{ trans('import.job_config_roles_do_map_value') }}
- {% if data.headers[i] == '' %} - {{ trans('import.job_config_roles_colum_count') }} #{{ loop.index }} - {% else %} - {{ data.headers[i] }} - {% endif %} - - {% if data.examples[i]|length == 0 %} - {{ trans('import.job_config_roles_no_example') }} - {% else %} - {% for example in data.examples[i] %} - {{ example }}
- {% endfor %} - {% endif %} - -
- {{ Form.select(('role['~loop.index0~']'), - data.roles, - importJob.configuration['column-roles'][loop.index0], - {class: 'form-control'}) }} - - {{ Form.checkbox(('map['~loop.index0~']'),1, - importJob.configuration['column-do-mapping'][loop.index0] - - ) }} -
- -
-
-
-
- -
-
-
-
- -
-
-
-
-
- - -{% endblock %} diff --git a/resources/views/v1/import/fints/choose_account.twig b/resources/views/v1/import/fints/choose_account.twig deleted file mode 100644 index f658988c8b..0000000000 --- a/resources/views/v1/import/fints/choose_account.twig +++ /dev/null @@ -1,44 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
- - -
-
-
-
-

{{ trans('import.job_config_input') }}

-
-
- {{ ExpandedForm.select('fints_account', data.fints_accounts, data.fints_account, {helpText: trans('import.job_config_fints_account_help'), required: true}) }} -
-
- {{ ExpandedForm.select('local_account', data.local_accounts, data.local_account, {helpText: trans('import.job_config_local_account_help'), required: true}) }} -
-
- {{ ExpandedForm.date('from_date', data.from_date, {required: true}) }} -
-
- {{ ExpandedForm.date('to_date', data.to_date, {required: true}) }} -
-
-
-
-
-
-
-
- -
-
-
-
-
-{% endblock %} diff --git a/resources/views/v1/import/fints/new.twig b/resources/views/v1/import/fints/new.twig deleted file mode 100644 index a5858e7be8..0000000000 --- a/resources/views/v1/import/fints/new.twig +++ /dev/null @@ -1,40 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
- - -
-
-
-
-

{{ trans('import.job_config_input') }}

-
-
- {{ ExpandedForm.text('fints_url', data.fints_url, {helpText: trans('import.job_config_fints_url_help'), required: true}) }} - {{ ExpandedForm.text('fints_port', data.fints_port, {helpText: trans('import.job_config_fints_port_help'), required: true}) }} - {{ ExpandedForm.text('fints_bank_code', data.fints_bank_code, {required: true}) }} - {{ ExpandedForm.text('fints_username', data.fints_username, {helpText: trans('import.job_config_fints_username_help'), required: false}) }} - {{ ExpandedForm.password('fints_password', {required: true}) }} - {{ ExpandedForm.checkbox('apply_rules', 1, true) }} -
-
-
-
-
-
-
-
- -
-
-
-
-
-{% endblock %} diff --git a/resources/views/v1/import/index.twig b/resources/views/v1/import/index.twig deleted file mode 100644 index da24b04a3e..0000000000 --- a/resources/views/v1/import/index.twig +++ /dev/null @@ -1,101 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
-
-
-

{{ trans('firefly.import_index_title') }}

-
-
-

- {{ trans('import.general_index_intro') }} -

-

- {{ trans('import.final_csv_import')|raw }} -

-
- {% for name, provider in providers %} - {# button for each import thing: #} -
- {% if not provider.allowed_for_demo and isDemoUser %} - {{ trans(('import.button_'~name)) }}
- {{ trans(('import.button_'~name)) }}
- ({{ trans('import.disabled_for_demo_user') }}) - {% else %} - - {{ trans(('import.button_'~name)) }}
- {{ trans(('import.button_'~name)) }} -
- {% endif %} -
- - {% endfor %} -
-
-
-
-
-
-
-

{{ trans('firefly.import_tools_title') }}

-
- -
-
-
- -
-
-
-
-

{{ trans('import.need_prereq_title') }}

-
-
-

- {{ trans('import.need_prereq_intro') }} -

-
    - {% for name, provider in providers %} - {% if provider.has_prereq %} -
  • - {% if provider.prereq_complete %} - - {% else %} - - {% endif %} - {{ trans('import.do_prereq_'~name) }} -
  • - {% endif %} - {% endfor %} -
-
-
-
-
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/spectre/accounts.twig b/resources/views/v1/import/spectre/accounts.twig deleted file mode 100644 index 4fbf0ba248..0000000000 --- a/resources/views/v1/import/spectre/accounts.twig +++ /dev/null @@ -1,107 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
- - -
-
-
-

{{ trans('import.job_config_spectre_apply_rules') }}

-
-
-
-
-

- {{ trans('import.job_config_spectre_apply_rules_text') }} -

- {{ ExpandedForm.checkbox('apply_rules', 1, true) }} -
-
- -
-
-
- -
-
-
-

{{ trans('import.job_config_spectre_accounts_title') }}

-
-
-
-
-

- {{ trans('import.job_config_spectre_accounts_text', {count: data.accounts|length,country: data.login.getCountryCode(),name: data.login.getProviderName()}) }} -

-
-
-
-
- - - - - - - - - {% for account in data.accounts %} - - - - - - {% endfor %} - -
{{ trans('list.account_on_spectre') }}{{ trans('list.account') }}
- {{ account.getNature()|capitalize }} "{{ account.getName() }}" - ({{ formatAmountBySymbol(account.getBalance(), account.getCurrencyCode()~' ') }})
- {% set currentIban = '' %} - {% for name, value in account.getExtra() %} - {% if not value is iterable and name != 'sort_code' and name !='current_date' and name != 'available_amount' and name !='current_time' and name != 'last_posted_transaction_id' %} - {{ trans('import.spectre_extra_key_'~name) }}: {{ value }}
- {% endif %} - {% if name == 'available_amount' %} - {{ trans('import.spectre_extra_key_'~name) }}: {{ formatAmountBySymbol(value, account.getCurrencyCode()~' ') }} - {% endif %} - {% if name == 'iban' %} - {% set currentIban = value %} - {% endif %} - {% endfor %} -
- -
- - -
-
- -
-
- -
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/spectre/choose-login.twig b/resources/views/v1/import/spectre/choose-login.twig deleted file mode 100644 index 61394d0402..0000000000 --- a/resources/views/v1/import/spectre/choose-login.twig +++ /dev/null @@ -1,87 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
- -
-
-
-

{{ trans('import.job_config_spectre_login_title') }}

-
-
-
-
-

- {{ trans('import.job_config_spectre_login_text', {count: data.logins|length}) }} -

-
-
- -
-
- - - - - - - - - - - {% for login in data.logins %} - - - - - - - - {% endfor %} - - - - - -
 {{ trans('list.spectre_bank') }}{{ trans('list.spectre_last_use') }}{{ trans('list.spectre_status') }}
- - - - - {{ login.getLastSuccessAt().formatLocalized(monthAndDayFormat) }}
- {{ login.getUpdatedAt().format("Y-m-d H:i:s") }}
-
- {{ trans('import.spectre_login_status_'~login.getStatus()) }} -
- - - -
-
-
- -
-
- -
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/spectre/prerequisites.twig b/resources/views/v1/import/spectre/prerequisites.twig deleted file mode 100644 index 1a1909bc0a..0000000000 --- a/resources/views/v1/import/spectre/prerequisites.twig +++ /dev/null @@ -1,57 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
- -
-
-
-

{{ trans('import.prereq_spectre_title') }}

-
-
-
-
-

- {{ trans('import.prereq_spectre_text')|raw }} -

-
-
- -
-
- {{ ExpandedForm.text('app_id', app_id) }} - {{ ExpandedForm.text('secret', secret) }} -
-
-
-
-

{{ trans('import.prereq_spectre_pub')|raw }}

-
- - -
- -
-
-
-
- -
-
- -
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/spectre/redirect.twig b/resources/views/v1/import/spectre/redirect.twig deleted file mode 100644 index 22c838e691..0000000000 --- a/resources/views/v1/import/spectre/redirect.twig +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - Page Redirection - - -If you are not redirected automatically, follow this link to Spectre.. - - diff --git a/resources/views/v1/import/status.twig b/resources/views/v1/import/status.twig deleted file mode 100644 index 7c9b0fbf91..0000000000 --- a/resources/views/v1/import/status.twig +++ /dev/null @@ -1,196 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} - - {# Initial display. Will refresh (and disappear almost immediately. #} -
-
-
-
-

{{ trans('import.status_wait_title') }}

-
-
-

- {{ trans('import.status_wait_text') }} -

-
-
-
-
- - {# Fatal error display. Will be shown (duh) when something goes horribly wrong. #} - - {# box to show when job is running ... #} - - - {# Box for when the job is ready to start - - #} - - {# Box for when the job is running! - - #} - {# displays the finished status of the import #} - - {# box to show error information. #} - {# - - #} - -{% endblock %} -{% block scripts %} - - -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/ynab/accounts.twig b/resources/views/v1/import/ynab/accounts.twig deleted file mode 100644 index d4e3b8a718..0000000000 --- a/resources/views/v1/import/ynab/accounts.twig +++ /dev/null @@ -1,100 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
- - -
-
-
-

{{ trans('import.job_config_ynab_apply_rules') }}

-
-
-
-
-

- {{ trans('import.job_config_ynab_apply_rules_text') }} -

- {{ ExpandedForm.checkbox('apply_rules', 1, true) }} -
-
- -
-
-
- -
-
-
-

{{ trans('import.job_config_ynab_accounts_title') }}

-
-
-
-
-

- {{ trans('import.job_config_ynab_accounts_text', {count: data.accounts|length}) }} -

-
-
-
-
- - - - - - - - - {% for account in data.ynab_accounts %} - - - - - - {% endfor %} - -
{{ trans('list.account_on_ynab') }}{{ trans('list.account') }}
- {{ account.name }} ({{ trans('import.ynab_account_type_'~account.type) }}) - {% if account.closed %} -
{{ trans('import.ynab_account_closed') }} - {% endif %} - {% if account.deleted %} -
{{ trans('import.ynab_account_deleted') }} - {% endif %} -
- -
- - -
-
- -
-
- -
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/ynab/prerequisites.twig b/resources/views/v1/import/ynab/prerequisites.twig deleted file mode 100644 index c7faab048a..0000000000 --- a/resources/views/v1/import/ynab/prerequisites.twig +++ /dev/null @@ -1,69 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
- -
-
-
-

{{ trans('import.prereq_ynab_title') }}

-
-
-
-
-

- {{ trans('import.prereq_ynab_text')|raw }} -

- {% if not is_https %} -

- {{ trans('import.callback_not_tls') }} -

- {{ callback_uri }} -

- {% endif %} - {% if is_https %} -

- {{ trans('import.prereq_ynab_redirect')|raw }} -

- {{ callback_uri }} -

- {% endif %} -
-
- -
-
- {{ ExpandedForm.text('client_id', client_id) }} -
-
-
-
- {{ ExpandedForm.text('client_secret', client_secret) }} -
-
-
- -
-
-
-
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/import/ynab/redirect.twig b/resources/views/v1/import/ynab/redirect.twig deleted file mode 100644 index f241a7aa22..0000000000 --- a/resources/views/v1/import/ynab/redirect.twig +++ /dev/null @@ -1,14 +0,0 @@ - - - - - - - Page Redirection - - -If you are not redirected automatically, follow this link to YNAB.. - - diff --git a/resources/views/v1/import/ynab/select-budgets.twig b/resources/views/v1/import/ynab/select-budgets.twig deleted file mode 100644 index 1c6c37b8fd..0000000000 --- a/resources/views/v1/import/ynab/select-budgets.twig +++ /dev/null @@ -1,58 +0,0 @@ -{% extends "./layout/default" %} - -{% block breadcrumbs %} - {{ Breadcrumbs.render }} -{% endblock %} -{% block content %} -
-
- - -
-
-
-

{{ trans('import.job_config_ynab_select_budgets') }}

-
-
-
-
-

- {{ trans('import.job_config_ynab_select_budgets_text', {count: data.total}) }} -

- {% if data.available|length == 0 %} -

- {{ trans('import.job_config_ynab_no_budgets') }} -

- {% else %} - {{ ExpandedForm.select('budget_id', data.available) }} - {% endif %} - - {% if data.not_available|length > 0 %} -

- {{ trans('import.job_config_ynab_bad_currency') }} -

-
    - {% for budget in data.not_available %} -
  • {{ budget }}
  • - {% endfor %} -
- {% endif %} -
-
- -
-
-
-
-
-{% endblock %} -{% block scripts %} -{% endblock %} -{% block styles %} -{% endblock %} diff --git a/resources/views/v1/list/bills.twig b/resources/views/v1/list/bills.twig index bfbd960411..14dfa1e712 100644 --- a/resources/views/v1/list/bills.twig +++ b/resources/views/v1/list/bills.twig @@ -61,7 +61,7 @@ #} {% if entry.paid_dates|length == 0 and entry.pay_dates|length == 0 and entry.active %} - {{ trans('components.not_expected_period') }} + {{ trans('firefly.not_expected_period') }} {{ formatDate(entry.next_expected_match, monthAndDayFormat) }} @@ -75,11 +75,10 @@ #} {% if entry.paid_dates|length == 0 and entry.pay_dates|length > 0 and entry.active %} - {{ trans('components.not_or_not_yet') }} + {{ trans('firefly.bill_expected_date', {date: entry.next_expected_match_diff }) }} {% for date in entry.pay_dates %} - {#{{ formatDate(entry.next_expected_match, monthAndDayFormat) }}
#} {{ formatDate(date, monthAndDayFormat) }}
{% endfor %} diff --git a/resources/views/v1/list/piggy-banks.twig b/resources/views/v1/list/piggy-banks.twig index 7540d17509..a7f165bee3 100644 --- a/resources/views/v1/list/piggy-banks.twig +++ b/resources/views/v1/list/piggy-banks.twig @@ -1,7 +1,4 @@ -
- {{ piggyBanks.render|raw }} -
- +
@@ -13,86 +10,123 @@ - - {% for piggy in piggyBanks %} - - - - - - - - + {% for objectGroupOrder, objectGroup in piggyBanks %} + {% if objectGroup.piggy_banks|length > 0 %} + + + + + + {% for piggy in objectGroup.piggy_banks %} + + + + + + + + + + + - - - - - + + + + + + {% endfor %} + + + + {# handle #} + {# buttons #} + + + {# remove money #} + {# progress#} + {# add money #} + + + + + + {% endif %} {% endfor %} -
 
- {{ piggy.name }} - {% if piggy.attachments.count > 0 %} - - {% endif %} - - {{ formatAmountBySymbol(piggy.current_amount,piggy.currency_symbol,piggy.currency_decimal_places) }} -
 {{ objectGroup.object_group_title }}
+ {{ piggy.name }} + {% if piggy.attachments.count > 0 %} + + {% endif %} - + {{ formatAmountBySymbol(piggy.current_amount,piggy.currency_symbol,piggy.currency_decimal_places) }} +
   + {% for sum in objectGroup.sums %} + {{ formatAmountBySymbol(sum.saved, sum.currency_symbol, sum.currency_decimal_places) }}
+ {% endfor %} +
-
- {{ piggyBanks.render|raw }} -
diff --git a/resources/views/v1/object-groups/delete.twig b/resources/views/v1/object-groups/delete.twig new file mode 100644 index 0000000000..aee112d1a9 --- /dev/null +++ b/resources/views/v1/object-groups/delete.twig @@ -0,0 +1,42 @@ +{% extends "./layout/default" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.render(Route.getCurrentRoute.getName, objectGroup) }} +{% endblock %} + +{% block content %} + +
+ +
+
+
+
+

{{ trans('form.delete_object_group', {'title': objectGroup.title}) }}

+
+
+

+ {{ trans('form.permDeleteWarning') }} +

+ +

+ {{ trans('form.object_group_areYouSure', {'title': objectGroup.title}) }} +

+ + {% if piggyBanks > 0 %} +

+ {{ Lang.choice('form.not_delete_piggy_banks', piggyBanks, {count: piggyBanks}) }} +

+ {% endif %} + +
+ +
+
+
+ +
+{% endblock %} diff --git a/resources/views/v1/object-groups/edit.twig b/resources/views/v1/object-groups/edit.twig new file mode 100644 index 0000000000..c0b4f8144f --- /dev/null +++ b/resources/views/v1/object-groups/edit.twig @@ -0,0 +1,58 @@ +{% extends "./layout/default" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.render(Route.getCurrentRoute.getName, objectGroup) }} +{% endblock %} + +{% block content %} + {{ Form.model(objectGroup, {'class' : 'form-horizontal','enctype': 'multipart/form-data','id' : 'update','url' : route('object-groups.update',objectGroup.id)}) }} + + + +
+
+
+
+

{{ 'mandatoryFields'|_ }}

+
+
+ {{ ExpandedForm.text('title') }} +
+
+ +
+
+
+
+ {# panel for options #} +
+
+

{{ 'options'|_ }}

+
+
+ {{ ExpandedForm.optionsList('update','object group') }} +
+ +
+ +
+
+ +{% endblock %} +{% block scripts %} + + + + {# auto complete for object groups #} + + +{% endblock %} + +{% block styles %} + + +{% endblock %} diff --git a/resources/views/v1/object-groups/index.twig b/resources/views/v1/object-groups/index.twig new file mode 100644 index 0000000000..b96860ab9e --- /dev/null +++ b/resources/views/v1/object-groups/index.twig @@ -0,0 +1,74 @@ +{% extends "./layout/default" %} + +{% block breadcrumbs %} + {{ Breadcrumbs.render }} +{% endblock %} +{% block content %} +
+
+
+
+

{{ 'object_groups'|_ }}

+
+ {% if objectGroups|length == 0 %} +
+
+
+

+ {{ 'object_groups_empty_explain'|_ }} +

+
+
+
+ {% endif %} + {% if objectGroups|length > 0 %} +
+ + + + + + + + + + {% for objectGroup in objectGroups %} + + + + + + {% endfor %} + +
  + {{ 'object_group_title'|_ }} + +   +
+ {{ objectGroup.title }}
+ + {% for piggyBank in objectGroup.piggyBanks %} + - {{ 'piggy_bank'|_ }}: {{ piggyBank.name }}
+ {% endfor %} +
+ +
+
+ {% endif %} +
+
+
+{% endblock %} +{% block scripts %} + + +{% endblock %} +{% block styles %} +{% endblock %} diff --git a/resources/views/v1/partials/menu-sidebar.twig b/resources/views/v1/partials/menu-sidebar.twig index b4074ad486..c133b18ad6 100644 --- a/resources/views/v1/partials/menu-sidebar.twig +++ b/resources/views/v1/partials/menu-sidebar.twig @@ -148,6 +148,12 @@ {{ 'tags'|_ }} +
  • + + + {{ 'object_groups_menu_bar'|_ }} + +
  • @@ -158,32 +164,15 @@ -
  • - - - {{ 'tools'|_ }} - - - - - -
  • + {% if config('firefly.feature_flags.export') %} +
  • + + + {{ 'export_data_menu'|_ }} + +
  • + {% endif %}
  • @@ -213,7 +202,7 @@ {{ 'currencies'|_ }}
  • - {% if hasRole('owner') %} + {% if hasRole('owner') %}
  • diff --git a/resources/views/v1/piggy-banks/create.twig b/resources/views/v1/piggy-banks/create.twig index c3bc89076a..40043c920e 100644 --- a/resources/views/v1/piggy-banks/create.twig +++ b/resources/views/v1/piggy-banks/create.twig @@ -33,7 +33,7 @@ {{ ExpandedForm.date('targetdate') }} {{ ExpandedForm.textarea('notes', null, {helpText: trans('firefly.field_supports_markdown')} ) }} {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }} - {#{{ ExpandedForm.objectGroup('object_group') }}#} + {{ ExpandedForm.objectGroup() }}
  • @@ -63,6 +63,10 @@ + + {# auto complete for object groups #} + + {% endblock %} {% block styles %} diff --git a/resources/views/v1/piggy-banks/edit.twig b/resources/views/v1/piggy-banks/edit.twig index 397fea13eb..a7c5d0670f 100644 --- a/resources/views/v1/piggy-banks/edit.twig +++ b/resources/views/v1/piggy-banks/edit.twig @@ -36,6 +36,7 @@ {{ ExpandedForm.date('targetdate') }} {{ ExpandedForm.textarea('notes', null, {helpText: trans('firefly.field_supports_markdown')}) }} {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }} + {{ ExpandedForm.objectGroup() }}
    @@ -65,6 +66,9 @@ + {# auto complete for object groups #} + + {% endblock %} {% block styles %} diff --git a/resources/views/v1/piggy-banks/show.twig b/resources/views/v1/piggy-banks/show.twig index 9988da9c50..2030114f22 100644 --- a/resources/views/v1/piggy-banks/show.twig +++ b/resources/views/v1/piggy-banks/show.twig @@ -36,6 +36,12 @@ {{ 'account'|_ }} {{ piggyBank.account.name }} + {% if piggy.object_group_title %} + + {{ 'object_group'|_ }} + {{ piggy.object_group_title }} + + {% endif %} {{ 'target_amount'|_ }} diff --git a/resources/views/v1/recurring/create.twig b/resources/views/v1/recurring/create.twig index 9de42801dd..e8f3990e72 100644 --- a/resources/views/v1/recurring/create.twig +++ b/resources/views/v1/recurring/create.twig @@ -4,7 +4,7 @@ {% endblock %} {% block content %} -
    + {# row with recurrence information #}
    @@ -51,8 +51,8 @@ {# only correct way to do active checkbox #} {{ ExpandedForm.checkbox('active', 1) }} - {{ ExpandedForm.checkbox('apply_rules',1) }} + {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }}
    diff --git a/resources/views/v1/recurring/edit.twig b/resources/views/v1/recurring/edit.twig index b241cd4efd..244cd3d9bf 100644 --- a/resources/views/v1/recurring/edit.twig +++ b/resources/views/v1/recurring/edit.twig @@ -52,6 +52,7 @@ {# only correct way to do active checkbox #} {{ ExpandedForm.checkbox('active', 1, preFilled.active) }} {{ ExpandedForm.checkbox('apply_rules', 1, preFilled.apply_rules) }} + {{ ExpandedForm.file('attachments[]', {'multiple': 'multiple','helpText': trans('firefly.upload_max_file_size', {'size': uploadSize|filesize}) }) }} diff --git a/resources/views/v1/recurring/index.twig b/resources/views/v1/recurring/index.twig index e7e66f1027..c1b7cdd02e 100644 --- a/resources/views/v1/recurring/index.twig +++ b/resources/views/v1/recurring/index.twig @@ -56,6 +56,9 @@ + {% if rt.attachments > 0 %} + + {% endif %} {% if rt.active == false %}{% endif %} {{ rt.type|_ }}: {{ rt.title }} diff --git a/resources/views/v1/rules/index.twig b/resources/views/v1/rules/index.twig index e1090a2a00..61c8863a3c 100644 --- a/resources/views/v1/rules/index.twig +++ b/resources/views/v1/rules/index.twig @@ -107,6 +107,7 @@
    {# show which transactions would match #} + {% if rule.active %} @@ -115,7 +116,7 @@ - + {% endif %} {# duplicate rule #} diff --git a/resources/views/v2/auth/login.twig b/resources/views/v2/auth/login.twig new file mode 100644 index 0000000000..c30b7b73b8 --- /dev/null +++ b/resources/views/v2/auth/login.twig @@ -0,0 +1,106 @@ +{% extends "./layout/auth" %} +{% block content %} + {# error when logging in #} + {% if errors.has('email') %} +
    +
    + +
    {{ 'flash_error'|_ }}
    + {{ errors.get('email')[0] }} +
    +
    + {% endif %} + + {# error when logout force #} + {% if session('logoutMessage') %} +
    +
    + +
    + {{ session('logoutMessage') }} +
    +
    + {% endif %} + + {# default header #} +
    + +{% endblock %} diff --git a/resources/views/v2/auth/passwords/email.twig b/resources/views/v2/auth/passwords/email.twig new file mode 100644 index 0000000000..060f1a1b6e --- /dev/null +++ b/resources/views/v2/auth/passwords/email.twig @@ -0,0 +1,83 @@ +{% extends "./layout/auth" %} +{% block content %} + + + {% if errors|length > 0 %} +
    +
    + +
    {{ 'flash_error'|_ }}
    +

    + {{ 'problems_with_input'|_ }} +

    +
      + {% for error in errors.all %} +
    • {{ error }}
    • + {% endfor %} +
    +
    +
    + {% endif %} + + {# default header #} + + +{% endblock %} diff --git a/resources/views/v2/auth/passwords/reset.twig b/resources/views/v2/auth/passwords/reset.twig new file mode 100644 index 0000000000..267913a8e6 --- /dev/null +++ b/resources/views/v2/auth/passwords/reset.twig @@ -0,0 +1,113 @@ +{% extends "./layout/auth" %} +{% block content %} + + + {% if errors|length > 0 %} +
    +
    + +
    {{ 'flash_error'|_ }}
    +

    + {{ 'problems_with_input'|_ }} +

    +
      + {% for error in errors.all %} +
    • {{ error }}
    • + {% endfor %} +
    +
    +
    + + + + {% endif %} + + + + + + + {# default header #} + + +{% endblock %} diff --git a/resources/views/v2/auth/register.twig b/resources/views/v2/auth/register.twig new file mode 100644 index 0000000000..0d47e63345 --- /dev/null +++ b/resources/views/v2/auth/register.twig @@ -0,0 +1,116 @@ +{% extends "./layout/auth" %} +{% block content %} + {# alerts here #} + + {% if errors|length > 0 %} + + +
    +
    + +
    {{ 'problems_with_input'|_ }}
    +
      + {% for error in errors.all %} +
    • {{ error }}
    • + {% endfor %} +
    +
    +
    + + {% endif %} + + + + + {# default header #} + + + {% include 'partials.auth.password-modal' %} + + +{% endblock %} +{% block scripts %} + + + +{% endblock %} diff --git a/resources/views/v2/emails/access-token-created-html.twig b/resources/views/v2/emails/access-token-created-html.twig new file mode 100644 index 0000000000..ede3a2f044 --- /dev/null +++ b/resources/views/v2/emails/access-token-created-html.twig @@ -0,0 +1,13 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.access_token_created_body') }} +

    + +

    + {{ trans('email.access_token_created_explanation')|raw }} +

    + +

    + {{ trans('email.access_token_created_revoke', {url: route('profile.index') }) }} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/access-token-created-text.twig b/resources/views/v2/emails/access-token-created-text.twig new file mode 100644 index 0000000000..04d85cdf35 --- /dev/null +++ b/resources/views/v2/emails/access-token-created-text.twig @@ -0,0 +1,7 @@ +{% include 'emails.header-text' %} +{{ trans('email.access_token_created_body')|raw }} + +{{ trans('email.access_token_created_explanation')|striptags|raw }} + +{{ trans('email.access_token_created_revoke', {url: route('profile.index') })|raw }} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/admin-test-html.twig b/resources/views/v2/emails/admin-test-html.twig new file mode 100644 index 0000000000..6d343085b8 --- /dev/null +++ b/resources/views/v2/emails/admin-test-html.twig @@ -0,0 +1,5 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.admin_test_body', {email: email })}} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/admin-test-text.twig b/resources/views/v2/emails/admin-test-text.twig new file mode 100644 index 0000000000..e6c5aca702 --- /dev/null +++ b/resources/views/v2/emails/admin-test-text.twig @@ -0,0 +1,3 @@ +{% include 'emails.header-text' %} +{{ trans('email.admin_test_body', {email: email })|raw }} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/confirm-email-change-html.twig b/resources/views/v2/emails/confirm-email-change-html.twig new file mode 100644 index 0000000000..7eb907c421 --- /dev/null +++ b/resources/views/v2/emails/confirm-email-change-html.twig @@ -0,0 +1,18 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.email_change_body_to_new')}} +

    +

    + {{trans('email.email_change_old', { email: oldEmail }) }} +

    +

    + {{trans('email.email_change_new_strong', { email: newEmail })|raw }} +

    +

    + {{ trans('email.email_change_instructions')}} +

    + +

    + {{ uri }} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/confirm-email-change-text.twig b/resources/views/v2/emails/confirm-email-change-text.twig new file mode 100644 index 0000000000..1fd8695814 --- /dev/null +++ b/resources/views/v2/emails/confirm-email-change-text.twig @@ -0,0 +1,10 @@ +{% include 'emails.header-text' %} +{{ trans('email.email_change_body_to_new')|raw }} + +{{trans('email.email_change_old', { email: oldEmail })|raw }} + +{{trans('email.email_change_new', { email: newEmail })|raw }} + +{{ trans('email.email_change_instructions')|raw }} +{{ uri }} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/error-html.twig b/resources/views/v2/emails/error-html.twig new file mode 100644 index 0000000000..d90bc67879 --- /dev/null +++ b/resources/views/v2/emails/error-html.twig @@ -0,0 +1,45 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.error_intro', { version: version, errorMessage: errorMessage })|raw }} +

    + +

    + {{ trans('email.error_type', {class: class }) }} +

    + +

    + {{ trans('email.error_timestamp', {time: time }) }} + +

    + +

    + {{ trans('email.error_location', { file: file, line: line, code: code })|raw }} +

    + +

    + {% if loggedIn %} + {{ trans('email.error_user', { id: user.id, email: user.email })|raw }} + {% else %} + {{ trans('email.error_no_user') }} + {% endif %} +

    + +

    + {{ trans('email.error_ip', { ip: ip }) }}
    + {{ trans('email.error_url', {url :url }) }}
    + {{ trans('email.error_user_agent', {userAgent: userAgent }) }} +

    + +

    + {{ trans('email.error_stacktrace')|raw }} +

    +

    + {{ trans('email.error_github_html')|raw }} +

    + +

    + {{ trans('email.error_stacktrace_below') }}

    +

    + {{ stackTrace|nl2br }} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/error-text.twig b/resources/views/v2/emails/error-text.twig new file mode 100644 index 0000000000..35e4a46334 --- /dev/null +++ b/resources/views/v2/emails/error-text.twig @@ -0,0 +1,27 @@ +{% include 'emails.header-text' %} +{{ trans('email.error_intro', { version: version, errorMessage: errorMessage })|striptags|raw }} + +{{ trans('email.error_type', {class: class })|raw }} + +{{ trans('email.error_timestamp', {time: time })|raw }} + +{{ trans('email.error_location', { file: file , line: line, code: code })|striptags|raw }} + +{% if loggedIn %} +{{ trans('email.error_user', { id: user.id, email: user.email })|striptags|raw }} +{% else %} +{{ trans('email.error_no_user')|raw }} +{% endif %} + +{{ trans('email.error_ip', { ip: ip }) }} +{{ trans('email.error_url', {url :url}) }} +{{ trans('email.error_user_agent', {userAgent: userAgent } ) }} + +{{ trans('email.error_stacktrace')|striptags|raw }} + +{{ trans('email.error_github_text' )|raw }} + +{{ trans('email.error_stacktrace_below')|raw }} + +{{ stackTrace|raw }} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/footer-html.twig b/resources/views/v2/emails/footer-html.twig new file mode 100644 index 0000000000..a5caad932a --- /dev/null +++ b/resources/views/v2/emails/footer-html.twig @@ -0,0 +1,13 @@ +

    + {{ trans('email.closing') }} +

    +

    + {{ trans('email.signature') }} +

    + +

    + {{ trans('email.footer_ps', {ipAddress: ipAddress}) }} +

    + + + diff --git a/resources/views/v2/emails/footer-text.twig b/resources/views/v2/emails/footer-text.twig new file mode 100644 index 0000000000..54a6c6b68d --- /dev/null +++ b/resources/views/v2/emails/footer-text.twig @@ -0,0 +1,6 @@ + +{{ trans('email.closing')|raw }} + +{{ trans('email.signature')|raw }} + +{{ trans('email.footer_ps', {ipAddress: ipAddress})|raw }} diff --git a/resources/views/v2/emails/header-html.twig b/resources/views/v2/emails/header-html.twig new file mode 100644 index 0000000000..d4e89e3255 --- /dev/null +++ b/resources/views/v2/emails/header-html.twig @@ -0,0 +1,10 @@ + + + + + + + +

    + {{ trans('email.greeting') }} +

    diff --git a/resources/views/v2/emails/header-text.twig b/resources/views/v2/emails/header-text.twig new file mode 100644 index 0000000000..16cd8490c4 --- /dev/null +++ b/resources/views/v2/emails/header-text.twig @@ -0,0 +1,2 @@ +{{ trans('email.greeting')|raw }} + diff --git a/resources/views/v2/emails/oauth-client-created-html.twig b/resources/views/v2/emails/oauth-client-created-html.twig new file mode 100644 index 0000000000..03906957f1 --- /dev/null +++ b/resources/views/v2/emails/oauth-client-created-html.twig @@ -0,0 +1,13 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.oauth_created_body', { name:client.name, url: client.redirect })|raw }} +

    + +

    + {{ trans('email.oauth_created_explanation')|raw }} +

    + +

    + {{ trans('email.oauth_created_undo', { url:route('profile.index')}) }} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/oauth-client-created-text.twig b/resources/views/v2/emails/oauth-client-created-text.twig new file mode 100644 index 0000000000..566f2ad89b --- /dev/null +++ b/resources/views/v2/emails/oauth-client-created-text.twig @@ -0,0 +1,7 @@ +{% include 'emails.header-text' %} +{{ trans('email.oauth_created_body', {name: client.name, url: client.redirect })|striptags|raw }} + +{{ trans('email.oauth_created_explanation')|striptags|raw }} + +{{ trans('email.oauth_created_undo', { url:route('profile.index')})|raw }} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/password-html.twig b/resources/views/v2/emails/password-html.twig new file mode 100644 index 0000000000..2f020fb924 --- /dev/null +++ b/resources/views/v2/emails/password-html.twig @@ -0,0 +1,13 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.reset_pw_instructions') }} +

    + +

    + {{ trans('email.reset_pw_warning')|raw }} +

    + +

    + {{ url }} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/password-text.twig b/resources/views/v2/emails/password-text.twig new file mode 100644 index 0000000000..258521ea99 --- /dev/null +++ b/resources/views/v2/emails/password-text.twig @@ -0,0 +1,7 @@ +{% include 'emails.header-text' %} +{{ trans('email.reset_pw_instructions')|raw }} + +{{ trans('email.reset_pw_warning')|striptags|raw }} + +{{ url }} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/registered-html.twig b/resources/views/v2/emails/registered-html.twig new file mode 100644 index 0000000000..78d8b1052e --- /dev/null +++ b/resources/views/v2/emails/registered-html.twig @@ -0,0 +1,20 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.registered_welcome', {address: address})|raw }} +

    + +
      +
    • + {{ trans('email.registered_pw', {address: address})|raw }} +
    • +
    • + {{ trans('email.registered_help')}} +
    • +
    • + {{ trans('email.registered_doc_html')|raw }} +
    • +
    +

    + {{ trans('email.registered_closing')}} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/registered-text.twig b/resources/views/v2/emails/registered-text.twig new file mode 100644 index 0000000000..78c696b065 --- /dev/null +++ b/resources/views/v2/emails/registered-text.twig @@ -0,0 +1,21 @@ +{% include 'emails.header-text' %} + +{{ trans('email.registered_welcome')|striptags|raw }} + +* {{ trans('email.registered_pw')|striptags|raw }} +* {{ trans('email.registered_help')|raw }} +* {{ trans('email.registered_doc_text')|raw }} + +{{ trans('email.registered_closing')|raw }} + +{{ trans('email.registered_firefly_iii_link')|raw }} +{{ address }} + +{{ trans('email.registered_pw_reset_link')|raw }} +{{ address }}/password/reset + +{{ trans('email.registered_doc_link')}} +https://github.com/firefly-iii/firefly-iii +https://firefly-iii.org/ + +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/report-new-journals-html.twig b/resources/views/v2/emails/report-new-journals-html.twig new file mode 100644 index 0000000000..c4414ae4ed --- /dev/null +++ b/resources/views/v2/emails/report-new-journals-html.twig @@ -0,0 +1,78 @@ +{% include 'emails.header-html' %} +

    + {{ trans_choice('email.new_journals_header', transformed|length ) }} +

    + + +
      + {% for group in transformed %} +
    1. + {% set count = group.transactions|length %} + + {% if 1 == count %} + {% set journal = group.transactions[0] %} + {{ journal.description }}, + + {% if journal.type == 'deposit' %} + + {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }} + {% if null != journal.foreign_amount*-1 %} + ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) + {% endif %} + + {% elseif journal.type == 'transfer' %} + + {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }} + {% if null != journal.foreign_amount %} + ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) + {% endif %} + + {% else %} + + {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }} + {% if null != journal.foreign_amount %} + ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) + {% endif %} + + + {% endif %} + + {% else %} + {{ group.group_title }} +
        + {% for journal in group.transactions %} +
      1. + {{ journal.description }}, + + {% if journal.type == 'deposit' %} + + {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }} + {% if null != journal.foreign_amount*-1 %} + ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) + {% endif %} + + {% elseif journal.type == 'transfer' %} + + {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }} + {% if null != journal.foreign_amount %} + ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) + {% endif %} + + {% else %} + + {{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }} + {% if null != journal.foreign_amount %} + ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}) + {% endif %} + + + {% endif %} +
      2. + {% endfor %} +
      + {% endif %} +
    2. + {% endfor %} +
    + +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/report-new-journals-text.twig b/resources/views/v2/emails/report-new-journals-text.twig new file mode 100644 index 0000000000..fe6455141c --- /dev/null +++ b/resources/views/v2/emails/report-new-journals-text.twig @@ -0,0 +1,16 @@ +{% include 'emails.header-text' %} +{{ trans_choice('email.new_journals_header', transformed|length )|raw }} + + +{% for group in transformed %} +{% set count = group.transactions|length %} +{% if 1 == count %}{% set journal = group.transactions[0] %} +- {{ journal.description }}, {% if journal.type == 'deposit' %}{{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }}{% if null != journal.foreign_amount*-1 %} ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}){% endif %}{% elseif journal.type == 'transfer' %}{{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }}{% if null != journal.foreign_amount %} ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}){% endif %}{% else %}{{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }}{% if null != journal.foreign_amount %} ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}){% endif %}{% endif %} + +{% else %}- {{ group.group_title }} +{% for journal in group.transactions %}-- {{ journal.description }}, {% if journal.type == 'deposit' %}{{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }}{% if null != journal.foreign_amount*-1 %} ({{ formatAmountBySymbol(journal.foreign_amount, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}){% endif %}{% elseif journal.type == 'transfer' %}{{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }}{% if null != journal.foreign_amount %} ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}){% endif %}{% else %}{{ formatAmountBySymbol(journal.amount*-1, journal.currency_symbol, journal.currency_decimal_places, false) }}{% if null != journal.foreign_amount %} ({{ formatAmountBySymbol(journal.foreign_amount*-1, journal.foreign_currency_symbol, journal.foreign_currency_decimal_places, false) }}){% endif %}{% endif %} + +{% endfor %} +{% endif %} +{% endfor %} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/emails/undo-email-change-html.twig b/resources/views/v2/emails/undo-email-change-html.twig new file mode 100644 index 0000000000..00bc5bb7a4 --- /dev/null +++ b/resources/views/v2/emails/undo-email-change-html.twig @@ -0,0 +1,17 @@ +{% include 'emails.header-html' %} +

    + {{ trans('email.email_change_body_to_old')|raw }} +

    +

    + {{ trans('email.email_change_ignore') }} +

    +

    + {{trans('email.email_change_old_strong', { email: oldEmail })|raw }} +

    +

    + {{trans('email.email_change_new', { email: newEmail }) }} +

    +

    + {{trans('email.email_change_undo_link')}} {{ uri }} +

    +{% include 'emails.footer-html' %} diff --git a/resources/views/v2/emails/undo-email-change-text.twig b/resources/views/v2/emails/undo-email-change-text.twig new file mode 100644 index 0000000000..2c719b9e4d --- /dev/null +++ b/resources/views/v2/emails/undo-email-change-text.twig @@ -0,0 +1,11 @@ +{% include 'emails.header-text' %} +{{ trans('email.email_change_body_to_old')|striptags|raw }} + +{{ trans('email.email_change_ignore')|raw }} + +{{trans('email.email_change_old', { email: oldEmail })|raw }} + +{{trans('email.email_change_new', { email: newEmail })|raw }} + +{{ trans('email.email_change_undo_link')|raw }} {{ uri }} +{% include 'emails.footer-text' %} diff --git a/resources/views/v2/errors/FireflyException.twig b/resources/views/v2/errors/FireflyException.twig new file mode 100644 index 0000000000..5617c4994f --- /dev/null +++ b/resources/views/v2/errors/FireflyException.twig @@ -0,0 +1,80 @@ + + + + + + + AdminLTE 3 | 500 Error + + + + + + + + + +
    +
    +
    +
    +

    500

    + +
    +

    {{ trans('errors.error_occurred') }}

    + +

    + {{ trans('errors.error_not_recoverable') }} +

    +

    + {{ exception.getMessage |default('General unknown errror') }} +

    + + {% if not debug %} +

    + {{ trans('errors.more_info') }} +

    +

    + {{ trans('errors.collect_info')|raw }} + {{ trans('errors.collect_info_more')|raw }} +

    +

    + {{ trans('errors.github_help') }} +

    +

    + {{ trans('errors.github_instructions')|raw }} +

    +
      +
    1. {{ trans('errors.use_search') }}
    2. +
    3. {{ trans('errors.include_info', { link: route('debug') })|raw }}
    4. +
    5. {{ trans('errors.tell_more') }}
    6. +
    7. {{ trans('errors.include_logs') }}
    8. +
    9. {{ trans('errors.what_did_you_do') }}
    10. +
    + {% endif %} + +
    +
    +
    +
    + + {% if debug %} +
    +
    +

    {{ trans('errors.error') }}

    +

    + {{ trans('errors.error_location', {file: exception.getFile, line: exception.getLine, code: exception.getCode })|raw }} +

    +

    + {{ trans('errors.stacktrace') }} +

    +
    + {{ exception.getTraceAsString|nl2br }} +
    +
    +
    + {% endif %} + +
    + + diff --git a/resources/views/v2/index.twig b/resources/views/v2/index.twig new file mode 100644 index 0000000000..832f15de7c --- /dev/null +++ b/resources/views/v2/index.twig @@ -0,0 +1,16 @@ +{% extends "./layout/default" %} +{% block content %} + + + +
    + +{% endblock %} + +{% block styles %} + +{% endblock %} + +{% block scripts %} + +{% endblock %} diff --git a/resources/views/v2/javascript/variables.twig b/resources/views/v2/javascript/variables.twig new file mode 100644 index 0000000000..d5131af423 --- /dev/null +++ b/resources/views/v2/javascript/variables.twig @@ -0,0 +1,3 @@ +var sessionStart = '{{ start }}'; +var sessionEnd = '{{ end }}'; + diff --git a/resources/views/v2/layout/auth.twig b/resources/views/v2/layout/auth.twig new file mode 100644 index 0000000000..1ce7466456 --- /dev/null +++ b/resources/views/v2/layout/auth.twig @@ -0,0 +1,23 @@ + + + + + + + Firefly III + {% if title != "Firefly" and title != "" %} + // {{ title }} + {% endif %} + + {% if subTitle %} + // {{ subTitle }} + {% endif %} + + + + + +{% block content %}{% endblock %} +{% block scripts %}{% endblock %} + + diff --git a/resources/views/v2/layout/default.twig b/resources/views/v2/layout/default.twig new file mode 100644 index 0000000000..0d3556cc80 --- /dev/null +++ b/resources/views/v2/layout/default.twig @@ -0,0 +1,100 @@ + + + + + + + + + + + + {% if subTitle %} + {{ subTitle }} » + {% endif %} + {% if title != "Firefly III" %} + {{ title }} » + {% endif %} + + Firefly III + + + + + + + +
    + + + {% include('partials.layout.navbar') %} + + + {% include('partials.layout.sidebar') %} + + +
    + +
    +
    +
    +
    +

    {% if mainTitleIcon %}{% endif %} + {{ title }} + {% if subTitleIcon %}{% endif %} + {{ subTitle }}

    +
    +
    + +
    +
    +
    +
    + + + +
    +
    + {% block content %}{% endblock %} +
    +
    + +
    + + {% include('partials.layout.footer') %} + + + + +
    + + + + + +{% block scripts %}{% endblock %} + + + + + + + + + + + + + + + + diff --git a/resources/views/v2/partials/auth/password-modal.twig b/resources/views/v2/partials/auth/password-modal.twig new file mode 100644 index 0000000000..4da1f437b4 --- /dev/null +++ b/resources/views/v2/partials/auth/password-modal.twig @@ -0,0 +1,36 @@ + + diff --git a/resources/views/v2/partials/layout/footer.twig b/resources/views/v2/partials/layout/footer.twig new file mode 100644 index 0000000000..c7e15dfc0f --- /dev/null +++ b/resources/views/v2/partials/layout/footer.twig @@ -0,0 +1,7 @@ + diff --git a/resources/views/v2/partials/layout/navbar.twig b/resources/views/v2/partials/layout/navbar.twig new file mode 100644 index 0000000000..bc36bab007 --- /dev/null +++ b/resources/views/v2/partials/layout/navbar.twig @@ -0,0 +1,113 @@ + + diff --git a/resources/views/v2/partials/layout/sidebar.twig b/resources/views/v2/partials/layout/sidebar.twig new file mode 100644 index 0000000000..707bee2dd9 --- /dev/null +++ b/resources/views/v2/partials/layout/sidebar.twig @@ -0,0 +1,254 @@ + diff --git a/routes/api.php b/routes/api.php index a18c9d34dd..2f5f5631de 100644 --- a/routes/api.php +++ b/routes/api.php @@ -54,6 +54,21 @@ Route::group( } ); +Route::group( + ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'groups', + 'as' => 'api.v1.object-groups.',], + static function () { + + // Accounts API routes: + Route::get('', ['uses' => 'ObjectGroupController@index', 'as' => 'index']); + Route::get('{objectGroup}', ['uses' => 'ObjectGroupController@show', 'as' => 'show']); + Route::put('{objectGroup}', ['uses' => 'ObjectGroupController@update', 'as' => 'update']); + Route::delete('{objectGroup}', ['uses' => 'ObjectGroupController@delete', 'as' => 'delete']); + + Route::get('{objectGroup}/piggy_banks', ['uses' => 'ObjectGroupController@piggyBanks', 'as' => 'piggy_banks']); + } +); + Route::group( ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'attachments', 'as' => 'api.v1.attachments.',], @@ -212,17 +227,6 @@ Route::group( } ); -Route::group( - ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'import', - 'as' => 'api.v1.import.',], - static function () { - - // Transaction Links API routes: - Route::get('list', ['uses' => 'ImportController@listAll', 'as' => 'list']); - Route::get('{importJob}', ['uses' => 'ImportController@show', 'as' => 'show']); - Route::get('{importJob}/transactions', ['uses' => 'ImportController@transactions', 'as' => 'transactions']); - } -); Route::group( ['namespace' => 'FireflyIII\Api\V1\Controllers', 'prefix' => 'link_types', 'as' => 'api.v1.link_types.',], diff --git a/routes/breadcrumbs.php b/routes/breadcrumbs.php index 2253421d53..925acccb50 100644 --- a/routes/breadcrumbs.php +++ b/routes/breadcrumbs.php @@ -29,8 +29,8 @@ use FireflyIII\Models\Bill; use FireflyIII\Models\Budget; use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\Category; -use FireflyIII\Models\ImportJob; use FireflyIII\Models\LinkType; +use FireflyIII\Models\ObjectGroup; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\Recurrence; use FireflyIII\Models\Rule; @@ -645,39 +645,6 @@ try { } ); - // IMPORT - Breadcrumbs::register( - 'import.index', - static function (BreadcrumbsGenerator $breadcrumbs) { - $breadcrumbs->parent('home'); - $breadcrumbs->push(trans('firefly.import_index_title'), route('import.index')); - } - ); - - Breadcrumbs::register( - 'import.prerequisites.index', - static function (BreadcrumbsGenerator $breadcrumbs, string $importProvider) { - $breadcrumbs->parent('import.index'); - $breadcrumbs->push(trans('import.prerequisites_breadcrumb_' . $importProvider), route('import.prerequisites.index', [$importProvider])); - } - ); - - Breadcrumbs::register( - 'import.job.configuration.index', - static function (BreadcrumbsGenerator $breadcrumbs, ImportJob $job) { - $breadcrumbs->parent('import.index'); - $breadcrumbs->push(trans('import.job_configuration_breadcrumb', ['key' => $job->key]), route('import.job.configuration.index', [$job->key])); - } - ); - - Breadcrumbs::register( - 'import.job.status.index', - static function (BreadcrumbsGenerator $breadcrumbs, ImportJob $job) { - $breadcrumbs->parent('import.index'); - $breadcrumbs->push(trans('import.job_status_breadcrumb', ['key' => $job->key]), route('import.job.status.index', [$job->key])); - } - ); - // PREFERENCES Breadcrumbs::register( 'preferences.index', @@ -1197,13 +1164,30 @@ try { } ); - // SPLIT + // object groups Breadcrumbs::register( - 'transactions.split.edit', - static function (BreadcrumbsGenerator $breadcrumbs, TransactionJournal $journal) { - $breadcrumbs->parent('transactions.show', $journal); - $breadcrumbs->push(trans('breadcrumbs.edit_journal', ['description' => $journal->description]), route('transactions.split.edit', [$journal->id])); + 'object-groups.index', + static function (BreadcrumbsGenerator $breadcrumbs): void { + $breadcrumbs->parent('index'); + $breadcrumbs->push(trans('firefly.object_groups_breadcrumb'), route('object-groups.index')); } ); + + Breadcrumbs::register( + 'object-groups.edit', + static function (BreadcrumbsGenerator $breadcrumbs, ObjectGroup $objectGroup) { + $breadcrumbs->parent('object-groups.index'); + $breadcrumbs->push(trans('breadcrumbs.edit_object_group', ['title' => $objectGroup->title]), route('object-groups.edit', [$objectGroup->id])); + } + ); + + Breadcrumbs::register( + 'object-groups.delete', + static function (BreadcrumbsGenerator $breadcrumbs, ObjectGroup $objectGroup) { + $breadcrumbs->parent('object-groups.index'); + $breadcrumbs->push(trans('breadcrumbs.delete_object_group', ['title' => $objectGroup->title]), route('object-groups.delete', [$objectGroup->id])); + } + ); + } catch (DuplicateBreadcrumbException $e) { } diff --git a/routes/web.php b/routes/web.php index 2c1eed8b34..28c843bb65 100644 --- a/routes/web.php +++ b/routes/web.php @@ -55,7 +55,7 @@ Route::group( // Password Reset Routes... Route::get('password/reset/{token}', ['uses' => 'Auth\ResetPasswordController@showResetForm', 'as' => 'password.reset']); Route::post('password/email', ['uses' => 'Auth\ForgotPasswordController@sendResetLinkEmail', 'as' => 'password.email']); - Route::post('password/reset', ['uses' => 'Auth\ResetPasswordController@reset']); + Route::post('password/reset', ['uses' => 'Auth\ResetPasswordController@reset', 'as' => 'password.reset.post']); Route::get('password/reset', ['uses' => 'Auth\ForgotPasswordController@showLinkRequestForm', 'as' => 'password.reset.request']); // Change email routes: @@ -546,40 +546,26 @@ Route::group( Route::get('export', ['uses' => 'Export\IndexController@export', 'as' => 'export']); } ); + + /** - * Import Controller. + * Object group controller. */ Route::group( - ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'import', 'as' => 'import.'], + ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'groups', 'as' => 'object-groups.'], static function () { - // index - Route::get('', ['uses' => 'Import\IndexController@index', 'as' => 'index']); + // index + Route::get('', ['uses' => 'ObjectGroup\IndexController@index', 'as' => 'index']); + Route::post('set-order/{objectGroup}', ['uses' => 'ObjectGroup\IndexController@setOrder', 'as' => 'set-order']); - // create new job - Route::get('create/{import_provider}', ['uses' => 'Import\IndexController@create', 'as' => 'create']); + // edit + Route::get('edit/{objectGroup}', ['uses' => 'ObjectGroup\EditController@edit', 'as' => 'edit']); + Route::post('update/{objectGroup}', ['uses' => 'ObjectGroup\EditController@update', 'as' => 'update']); - // set global prerequisites for an import source, possible with a job already attached. - Route::get('prerequisites/{import_provider}/{importJob?}', ['uses' => 'Import\PrerequisitesController@index', 'as' => 'prerequisites.index']); - Route::post('prerequisites/{import_provider}/{importJob?}', ['uses' => 'Import\PrerequisitesController@post', 'as' => 'prerequisites.post']); - - // configure a job: - Route::get('job/configuration/{importJob}', ['uses' => 'Import\JobConfigurationController@index', 'as' => 'job.configuration.index']); - Route::post('job/configuration/{importJob}', ['uses' => 'Import\JobConfigurationController@post', 'as' => 'job.configuration.post']); - - // get status of a job. This is also the landing page of a job after job config is complete. - Route::get('job/status/{importJob}', ['uses' => 'Import\JobStatusController@index', 'as' => 'job.status.index']); - Route::get('job/json/{importJob}', ['uses' => 'Import\JobStatusController@json', 'as' => 'job.status.json']); - - // start the job! - Route::any('job/start/{importJob}', ['uses' => 'Import\JobStatusController@start', 'as' => 'job.start']); - Route::any('job/store/{importJob}', ['uses' => 'Import\JobStatusController@store', 'as' => 'job.store']); - - // download config: - Route::get('download/{importJob}', ['uses' => 'Import\IndexController@download', 'as' => 'job.download']); - - // callback URI for YNAB OAuth. Sadly, needs a custom solution. - Route::get('ynab-callback', ['uses' => 'Import\CallbackController@ynab', 'as' => 'callback.ynab']); + // delete + Route::get('delete/{objectGroup}', ['uses' => 'ObjectGroup\DeleteController@delete', 'as' => 'delete']); + Route::post('destroy/{objectGroup}', ['uses' => 'ObjectGroup\DeleteController@destroy', 'as' => 'destroy']); } ); @@ -594,7 +580,7 @@ Route::group( ); /** - * Budget Controller. + * JScript Controller. */ Route::group( ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'v1/jscript', 'as' => 'javascript.'], @@ -605,6 +591,16 @@ Route::group( } ); +/** + * JScript Controller. + */ +Route::group( + ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'v2/jscript', 'as' => 'javascript.v2.'], + static function () { + Route::get('variables', ['uses' => 'JavascriptController@variablesV2', 'as' => 'variables']); + } +); + /** * JSON Controller(s). */ @@ -618,6 +614,7 @@ Route::group( Route::get('expense-accounts', ['uses' => 'Json\AutoCompleteController@expenseAccounts', 'as' => 'autocomplete.expense-accounts']); Route::get('asset-accounts', ['uses' => 'Json\AutoCompleteController@assetAccounts', 'as' => 'autocomplete.asset-accounts']); Route::get('budgets', ['uses' => 'Json\AutoCompleteController@budgets', 'as' => 'autocomplete.budgets']); + Route::get('object-groups', ['uses' => 'Json\AutoCompleteController@objectGroups', 'as' => 'autocomplete.object-groups']); Route::get('bills', ['uses' => 'Json\AutoCompleteController@bills', 'as' => 'autocomplete.bills']); Route::get('categories', ['uses' => 'Json\AutoCompleteController@categories', 'as' => 'autocomplete.categories']); Route::get('currencies', ['uses' => 'Json\AutoCompleteController@currencies', 'as' => 'autocomplete.currencies']); @@ -672,22 +669,23 @@ Route::group( Route::group( ['middleware' => 'user-full-auth', 'namespace' => 'FireflyIII\Http\Controllers', 'prefix' => 'piggy-banks', 'as' => 'piggy-banks.'], static function () { - Route::get('', ['uses' => 'PiggyBankController@index', 'as' => 'index']); - Route::get('add/{piggyBank}', ['uses' => 'PiggyBankController@add', 'as' => 'add-money']); - Route::get('remove/{piggyBank}', ['uses' => 'PiggyBankController@remove', 'as' => 'remove-money']); - Route::get('add-money/{piggyBank}', ['uses' => 'PiggyBankController@addMobile', 'as' => 'add-money-mobile']); - Route::get('remove-money/{piggyBank}', ['uses' => 'PiggyBankController@removeMobile', 'as' => 'remove-money-mobile']); - Route::get('create', ['uses' => 'PiggyBankController@create', 'as' => 'create']); - Route::get('edit/{piggyBank}', ['uses' => 'PiggyBankController@edit', 'as' => 'edit']); - Route::get('delete/{piggyBank}', ['uses' => 'PiggyBankController@delete', 'as' => 'delete']); - Route::get('show/{piggyBank}', ['uses' => 'PiggyBankController@show', 'as' => 'show']); - Route::post('store', ['uses' => 'PiggyBankController@store', 'as' => 'store']); - Route::post('update/{piggyBank}', ['uses' => 'PiggyBankController@update', 'as' => 'update']); - Route::post('destroy/{piggyBank}', ['uses' => 'PiggyBankController@destroy', 'as' => 'destroy']); - Route::post('add/{piggyBank}', ['uses' => 'PiggyBankController@postAdd', 'as' => 'add']); - Route::post('remove/{piggyBank}', ['uses' => 'PiggyBankController@postRemove', 'as' => 'remove']); - Route::post('set-order/{piggyBank}', ['uses' => 'PiggyBankController@setOrder', 'as' => 'set-order']); + Route::get('', ['uses' => 'PiggyBank\IndexController@index', 'as' => 'index']); + Route::get('add/{piggyBank}', ['uses' => 'PiggyBank\AmountController@add', 'as' => 'add-money']); + Route::get('remove/{piggyBank}', ['uses' => 'PiggyBank\AmountController@remove', 'as' => 'remove-money']); + Route::get('add-money/{piggyBank}', ['uses' => 'PiggyBank\AmountController@addMobile', 'as' => 'add-money-mobile']); + Route::get('remove-money/{piggyBank}', ['uses' => 'PiggyBank\AmountController@removeMobile', 'as' => 'remove-money-mobile']); + Route::get('create', ['uses' => 'PiggyBank\CreateController@create', 'as' => 'create']); + Route::get('edit/{piggyBank}', ['uses' => 'PiggyBank\EditController@edit', 'as' => 'edit']); + Route::get('delete/{piggyBank}', ['uses' => 'PiggyBank\DeleteController@delete', 'as' => 'delete']); + Route::get('show/{piggyBank}', ['uses' => 'PiggyBank\ShowController@show', 'as' => 'show']); + Route::post('store', ['uses' => 'PiggyBank\CreateController@store', 'as' => 'store']); + Route::post('update/{piggyBank}', ['uses' => 'PiggyBank\EditController@update', 'as' => 'update']); + Route::post('destroy/{piggyBank}', ['uses' => 'PiggyBank\DeleteController@destroy', 'as' => 'destroy']); + Route::post('add/{piggyBank}', ['uses' => 'PiggyBank\AmountController@postAdd', 'as' => 'add']); + Route::post('remove/{piggyBank}', ['uses' => 'PiggyBank\AmountController@postRemove', 'as' => 'remove']); + + Route::post('set-order/{piggyBank}', ['uses' => 'PiggyBank\IndexController@setOrder', 'as' => 'set-order']); } ); diff --git a/tests/Feature/Controllers/Admin/UserControllerTest.php b/tests/Feature/Controllers/Admin/UserControllerTest.php index 3248765b33..e82302554e 100644 --- a/tests/Feature/Controllers/Admin/UserControllerTest.php +++ b/tests/Feature/Controllers/Admin/UserControllerTest.php @@ -128,7 +128,6 @@ class UserControllerTest extends TestCase $repository->shouldReceive('getUserData')->andReturn( [ 'export_jobs_success' => 0, - 'import_jobs_success' => 0, 'attachments_size' => 0, ] ); diff --git a/tests/TestCase.php b/tests/TestCase.php index 057517b80c..5b926b55d0 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -39,7 +39,6 @@ use FireflyIII\Models\BudgetLimit; use FireflyIII\Models\Category; use FireflyIII\Models\Configuration; use FireflyIII\Models\CurrencyExchangeRate; -use FireflyIII\Models\ImportJob; use FireflyIII\Models\PiggyBank; use FireflyIII\Models\PiggyBankEvent; use FireflyIII\Models\Preference; @@ -52,7 +51,6 @@ use FireflyIII\Models\TransactionJournal; use FireflyIII\Models\TransactionJournalLink; use FireflyIII\Models\TransactionType; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; -use FireflyIII\Transformers\TransactionTransformer; use FireflyIII\User; use Illuminate\Foundation\Testing\TestCase as BaseTestCase; use Log; @@ -72,21 +70,6 @@ use RuntimeException; abstract class TestCase extends BaseTestCase { - /** - * @return ImportJob - */ - public function getRandomPiggyBankEvent(): PiggyBankEvent - { - return PiggyBankEvent::inRandomOrder()->first(); - } - - /** - * @return ImportJob - */ - public function getRandomImportJob(): ImportJob - { - return $this->user()->importJobs()->inRandomOrder()->first(); - } /** * @return Recurrence */ diff --git a/tests/Unit/Middleware/BinderTest.php b/tests/Unit/Middleware/BinderTest.php index 458581eced..ca364a9233 100644 --- a/tests/Unit/Middleware/BinderTest.php +++ b/tests/Unit/Middleware/BinderTest.php @@ -28,11 +28,6 @@ use Carbon\Carbon; use FireflyIII\Helpers\Collector\GroupCollectorInterface; use FireflyIII\Helpers\Fiscal\FiscalHelperInterface; use FireflyIII\Http\Middleware\Binder; -use FireflyIII\Import\Prerequisites\BunqPrerequisites; -use FireflyIII\Import\Prerequisites\FakePrerequisites; -use FireflyIII\Import\Prerequisites\PrerequisitesInterface; -use FireflyIII\Import\Prerequisites\SpectrePrerequisites; -use FireflyIII\Import\Prerequisites\YnabPrerequisites; use FireflyIII\Models\AccountType; use FireflyIII\Models\AvailableBudget; use FireflyIII\Models\Preference; @@ -950,59 +945,6 @@ class BinderTest extends TestCase $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); } - /** - * @covers \FireflyIII\Http\Middleware\Binder - * @covers \FireflyIII\Models\ImportJob - */ - public function testImportJob(): void - { - Log::info(sprintf('Now in test %s.', __METHOD__)); - Route::middleware(Binder::class)->any( - '/_test/binder/{importJob}', function () { - return 'OK'; - } - ); - - $this->be($this->user()); - $response = $this->get('/_test/binder/testImport'); - $this->assertEquals(Response::HTTP_OK, $response->getStatusCode()); - } - - /** - * @covers \FireflyIII\Http\Middleware\Binder - * @covers \FireflyIII\Models\ImportJob - */ - public function testImportJobNotFound(): void - { - Log::info(sprintf('Now in test %s.', __METHOD__)); - Route::middleware(Binder::class)->any( - '/_test/binder/{importJob}', function () { - return 'OK'; - } - ); - - $this->be($this->user()); - $response = $this->get('/_test/binder/0'); - $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); - } - - /** - * @covers \FireflyIII\Http\Middleware\Binder - * @covers \FireflyIII\Models\ImportJob - */ - public function testImportJobNotLoggedIn(): void - { - Log::info(sprintf('Now in test %s.', __METHOD__)); - Route::middleware(Binder::class)->any( - '/_test/binder/{importJob}', function () { - return 'OK'; - } - ); - - $response = $this->get('/_test/binder/testImport'); - $this->assertEquals(Response::HTTP_NOT_FOUND, $response->getStatusCode()); - } - /** * @covers \FireflyIII\Http\Middleware\Binder * @covers \FireflyIII\Support\Binder\JournalList diff --git a/tests/Unit/Rules/IsValidAttachmentModelTest.php b/tests/Unit/Rules/IsValidAttachmentModelTest.php index 6f32da8457..29a2fb1a99 100644 --- a/tests/Unit/Rules/IsValidAttachmentModelTest.php +++ b/tests/Unit/Rules/IsValidAttachmentModelTest.php @@ -25,11 +25,9 @@ namespace Tests\Unit\Rules; use FireflyIII\Models\Bill; -use FireflyIII\Models\ImportJob; use FireflyIII\Models\Transaction; use FireflyIII\Models\TransactionJournal; use FireflyIII\Repositories\Bill\BillRepositoryInterface; -use FireflyIII\Repositories\ImportJob\ImportJobRepositoryInterface; use FireflyIII\Repositories\Journal\JournalAPIRepositoryInterface; use FireflyIII\Repositories\Journal\JournalRepositoryInterface; use FireflyIII\Rules\IsValidAttachmentModel; @@ -71,24 +69,6 @@ class IsValidAttachmentModelTest extends TestCase $this->assertTrue($engine->passes($attribute, $value)); } - /** - * @covers \FireflyIII\Rules\IsValidAttachmentModel - */ - public function testImportJob(): void - { - $job = $this->getRandomImportJob(); - $jobRepos = $this->mock(ImportJobRepositoryInterface::class); - - $jobRepos->shouldReceive('setUser')->atLeast()->once(); - $jobRepos->shouldReceive('find')->atLeast()->once()->withArgs([$job->id])->andReturn($job); - - $value = $job->id; - $attribute = 'not-important'; - $this->be($this->user()); - $engine = new IsValidAttachmentModel(ImportJob::class); - $this->assertTrue($engine->passes($attribute, $value)); - } - /** * @covers \FireflyIII\Rules\IsValidAttachmentModel */ diff --git a/tests/Unit/Transformers/ImportJobTransformerTest.php b/tests/Unit/Transformers/ImportJobTransformerTest.php deleted file mode 100644 index 1536297e9f..0000000000 --- a/tests/Unit/Transformers/ImportJobTransformerTest.php +++ /dev/null @@ -1,76 +0,0 @@ -. - */ - -declare(strict_types=1); - -namespace Tests\Unit\Transformers; - - -use FireflyIII\Models\ImportJob; -use FireflyIII\Transformers\ImportJobTransformer; -use Log; -use Symfony\Component\HttpFoundation\ParameterBag; -use Tests\TestCase; - -/** - * - * Class ImportJobTransformerTest - * @SuppressWarnings(PHPMD.CouplingBetweenObjects) - * @SuppressWarnings(PHPMD.ExcessiveMethodLength) - * @SuppressWarnings(PHPMD.TooManyPublicMethods) - */ -class ImportJobTransformerTest extends TestCase -{ - /** - * - */ - public function setUp(): void - { - parent::setUp(); - Log::info(sprintf('Now in %s.', get_class($this))); - } - - /** - * Basic coverage - * - * @covers \FireflyIII\Transformers\ImportJobTransformer - */ - public function testBasic(): void - { - - $job = ImportJob::first(); - $job->tag_id = 1; - $parameters = new ParameterBag; - $transformer = app(ImportJobTransformer::class); - $transformer->setParameters($parameters); - - $result = $transformer->transform($job); - - $this->assertEquals($job->key, $result['key']); - $this->assertEquals($job->tag_id, $result['tag_id']); - $this->assertEquals(json_encode($job->configuration), $result['configuration']); - $this->assertEquals(json_encode($job->extended_status), $result['extended_status']); - $this->assertEquals(json_encode($job->transactions), $result['transactions']); - $this->assertEquals(json_encode($job->errors), $result['errors']); - - - } -} diff --git a/yarn.lock b/yarn.lock index ac5baf9d85..85ca89350f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2,35 +2,35 @@ # yarn lockfile v1 -"@babel/code-frame@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.1.tgz#d5481c5095daa1c57e16e54c6f9198443afb49ff" - integrity sha512-IGhtTmpjGbYzcEDOw7DcQtbQSXcG9ftmAXtWTu9V936vDye4xjjekktFAtgZsWpzTj/X01jocB46mTywm/4SZw== +"@babel/code-frame@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.3.tgz#324bcfd8d35cd3d47dae18cde63d752086435e9a" + integrity sha512-fDx9eNW0qz0WkUeqL6tXEXzVlPh6Y5aCDEZesl0xBGA8ndRukX91Uk44ZqnkECp01NAZUdCAl+aiQNGi0k88Eg== dependencies: - "@babel/highlight" "^7.10.1" + "@babel/highlight" "^7.10.3" -"@babel/compat-data@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.1.tgz#b1085ffe72cd17bf2c0ee790fc09f9626011b2db" - integrity sha512-CHvCj7So7iCkGKPRFUfryXIkU2gSBw7VSZFYLsqVhrS47269VK2Hfi9S/YcublPMW8k1u2bQBlbDruoQEm4fgw== +"@babel/compat-data@^7.10.1", "@babel/compat-data@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.10.3.tgz#9af3e033f36e8e2d6e47570db91e64a846f5d382" + integrity sha512-BDIfJ9uNZuI0LajPfoYV28lX8kyCPMHY6uY4WH1lJdcicmAfxCK5ASzaeV0D/wsUaRH/cLk+amuxtC37sZ8TUg== dependencies: browserslist "^4.12.0" invariant "^2.2.4" semver "^5.5.0" "@babel/core@^7.0.0-beta.49", "@babel/core@^7.2.0": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.2.tgz#bd6786046668a925ac2bd2fd95b579b92a23b36a" - integrity sha512-KQmV9yguEjQsXqyOUGKjS4+3K8/DlOCE2pZcq4augdQmtTy5iv5EHtmMSJ7V4c1BIPjuwtZYqYLCq9Ga+hGBRQ== + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.10.3.tgz#73b0e8ddeec1e3fdd7a2de587a60e17c440ec77e" + integrity sha512-5YqWxYE3pyhIi84L84YcwjeEgS+fa7ZjK6IBVGTjDVfm64njkR2lfDhVR5OudLk8x2GK59YoSyVv+L/03k1q9w== dependencies: - "@babel/code-frame" "^7.10.1" - "@babel/generator" "^7.10.2" + "@babel/code-frame" "^7.10.3" + "@babel/generator" "^7.10.3" "@babel/helper-module-transforms" "^7.10.1" "@babel/helpers" "^7.10.1" - "@babel/parser" "^7.10.2" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.2" + "@babel/parser" "^7.10.3" + "@babel/template" "^7.10.3" + "@babel/traverse" "^7.10.3" + "@babel/types" "^7.10.3" convert-source-map "^1.7.0" debug "^4.1.0" gensync "^1.0.0-beta.1" @@ -40,12 +40,12 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.10.1", "@babel/generator@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.2.tgz#0fa5b5b2389db8bfdfcc3492b551ee20f5dd69a9" - integrity sha512-AxfBNHNu99DTMvlUPlt1h2+Hn7knPpH5ayJ8OqDWSeLld+Fi2AYBTC/IejWDM9Edcii4UzZRCsbUt0WlSDsDsA== +"@babel/generator@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.10.3.tgz#32b9a0d963a71d7a54f5f6c15659c3dbc2a523a5" + integrity sha512-drt8MUHbEqRzNR0xnF8nMehbY11b1SDkRw03PSNH/3Rb2Z35oxkddVSi3rcaak0YJQ86PCuE7Qx1jSFhbLNBMA== dependencies: - "@babel/types" "^7.10.2" + "@babel/types" "^7.10.3" jsesc "^2.5.1" lodash "^4.17.13" source-map "^0.5.0" @@ -58,12 +58,12 @@ "@babel/types" "^7.10.1" "@babel/helper-builder-binary-assignment-operator-visitor@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.1.tgz#0ec7d9be8174934532661f87783eb18d72290059" - integrity sha512-cQpVq48EkYxUU0xozpGCLla3wlkdRRqLWu1ksFMXA9CM5KQmyyRpSEsYXbao7JUkOw/tAaYKCaYyZq6HOFYtyw== + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.3.tgz#4e9012d6701bef0030348d7f9c808209bd3e8687" + integrity sha512-lo4XXRnBlU6eRM92FkiZxpo1xFLmv3VsPFk61zJKMm7XYJfwqXHsYJTY6agoc4a3L8QPw1HqWehO18coZgbT6A== dependencies: - "@babel/helper-explode-assignable-expression" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-explode-assignable-expression" "^7.10.3" + "@babel/types" "^7.10.3" "@babel/helper-compilation-targets@^7.10.2": version "7.10.2" @@ -77,14 +77,14 @@ semver "^5.5.0" "@babel/helper-create-class-features-plugin@^7.10.1": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.2.tgz#7474295770f217dbcf288bf7572eb213db46ee67" - integrity sha512-5C/QhkGFh1vqcziq1vAL6SI9ymzUp8BCYjFpvYVhWP4DlATIb3u5q3iUd35mvlyGs8fO7hckkW7i0tmH+5+bvQ== + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.3.tgz#2783daa6866822e3d5ed119163b50f0fc3ae4b35" + integrity sha512-iRT9VwqtdFmv7UheJWthGc/h2s7MqoweBF9RUj77NFZsg9VfISvBTum3k6coAhJ8RWv2tj3yUjA03HxPd0vfpQ== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-member-expression-to-functions" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-function-name" "^7.10.3" + "@babel/helper-member-expression-to-functions" "^7.10.3" + "@babel/helper-optimise-call-expression" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.3" "@babel/helper-replace-supers" "^7.10.1" "@babel/helper-split-export-declaration" "^7.10.1" @@ -97,59 +97,59 @@ "@babel/helper-regex" "^7.10.1" regexpu-core "^4.7.0" -"@babel/helper-define-map@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.1.tgz#5e69ee8308648470dd7900d159c044c10285221d" - integrity sha512-+5odWpX+OnvkD0Zmq7panrMuAGQBu6aPUgvMzuMGo4R+jUOvealEj2hiqI6WhxgKrTpFoFj0+VdsuA8KDxHBDg== +"@babel/helper-define-map@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.3.tgz#d27120a5e57c84727b30944549b2dfeca62401a8" + integrity sha512-bxRzDi4Sin/k0drWCczppOhov1sBSdBvXJObM1NLHQzjhXhwRtn7aRWGvLJWCYbuu2qUk3EKs6Ci9C9ps8XokQ== dependencies: - "@babel/helper-function-name" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-function-name" "^7.10.3" + "@babel/types" "^7.10.3" lodash "^4.17.13" -"@babel/helper-explode-assignable-expression@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.1.tgz#e9d76305ee1162ca467357ae25df94f179af2b7e" - integrity sha512-vcUJ3cDjLjvkKzt6rHrl767FeE7pMEYfPanq5L16GRtrXIoznc0HykNW2aEYkcnP76P0isoqJ34dDMFZwzEpJg== +"@babel/helper-explode-assignable-expression@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.10.3.tgz#9dc14f0cfa2833ea830a9c8a1c742b6e7461b05e" + integrity sha512-0nKcR64XrOC3lsl+uhD15cwxPvaB6QKUDlD84OT9C3myRbhJqTMYir69/RWItUvHpharv0eJ/wk7fl34ONSwZw== dependencies: - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/traverse" "^7.10.3" + "@babel/types" "^7.10.3" -"@babel/helper-function-name@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.1.tgz#92bd63829bfc9215aca9d9defa85f56b539454f4" - integrity sha512-fcpumwhs3YyZ/ttd5Rz0xn0TpIwVkN7X0V38B9TWNfVF42KEkhkAAuPCQ3oXmtTRtiPJrmZ0TrfS0GKF0eMaRQ== +"@babel/helper-function-name@^7.10.1", "@babel/helper-function-name@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.3.tgz#79316cd75a9fa25ba9787ff54544307ed444f197" + integrity sha512-FvSj2aiOd8zbeqijjgqdMDSyxsGHaMt5Tr0XjQsGKHD3/1FP3wksjnLAWzxw7lvXiej8W1Jt47SKTZ6upQNiRw== dependencies: - "@babel/helper-get-function-arity" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/helper-get-function-arity" "^7.10.3" + "@babel/template" "^7.10.3" + "@babel/types" "^7.10.3" -"@babel/helper-get-function-arity@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.1.tgz#7303390a81ba7cb59613895a192b93850e373f7d" - integrity sha512-F5qdXkYGOQUb0hpRaPoetF9AnsXknKjWMZ+wmsIRsp5ge5sFh4c3h1eH2pRTTuy9KKAA2+TTYomGXAtEL2fQEw== +"@babel/helper-get-function-arity@^7.10.1", "@babel/helper-get-function-arity@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.3.tgz#3a28f7b28ccc7719eacd9223b659fdf162e4c45e" + integrity sha512-iUD/gFsR+M6uiy69JA6fzM5seno8oE85IYZdbVVEuQaZlEzMO2MXblh+KSPJgsZAUx0EEbWXU0yJaW7C9CdAVg== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.3" -"@babel/helper-hoist-variables@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.1.tgz#7e77c82e5dcae1ebf123174c385aaadbf787d077" - integrity sha512-vLm5srkU8rI6X3+aQ1rQJyfjvCBLXP8cAGeuw04zeAM2ItKb1e7pmVmLyHb4sDaAYnLL13RHOZPLEtcGZ5xvjg== +"@babel/helper-hoist-variables@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.3.tgz#d554f52baf1657ffbd7e5137311abc993bb3f068" + integrity sha512-9JyafKoBt5h20Yv1+BXQMdcXXavozI1vt401KBiRc2qzUepbVnd7ogVNymY1xkQN9fekGwfxtotH2Yf5xsGzgg== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.3" -"@babel/helper-member-expression-to-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.1.tgz#432967fd7e12a4afef66c4687d4ca22bc0456f15" - integrity sha512-u7XLXeM2n50gb6PWJ9hoO5oO7JFPaZtrh35t8RqKLT1jFKj9IWeD1zrcrYp1q1qiZTdEarfDWfTIP8nGsu0h5g== +"@babel/helper-member-expression-to-functions@^7.10.1", "@babel/helper-member-expression-to-functions@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.10.3.tgz#bc3663ac81ac57c39148fef4c69bf48a77ba8dd6" + integrity sha512-q7+37c4EPLSjNb2NmWOjNwj0+BOyYlssuQ58kHEWk1Z78K5i8vTUsteq78HMieRPQSl/NtpQyJfdjt3qZ5V2vw== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.3" -"@babel/helper-module-imports@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.1.tgz#dd331bd45bccc566ce77004e9d05fe17add13876" - integrity sha512-SFxgwYmZ3HZPyZwJRiVNLRHWuW2OgE5k2nrVs6D9Iv4PPnXVffuEHy83Sfx/l4SqF+5kyJXjAyUmrG7tNm+qVg== +"@babel/helper-module-imports@^7.10.1", "@babel/helper-module-imports@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.3.tgz#766fa1d57608e53e5676f23ae498ec7a95e1b11a" + integrity sha512-Jtqw5M9pahLSUWA+76nhK9OG8nwYXzhQzVIGFoNaHnXF/r4l7kz4Fl0UAW7B6mqC5myoJiBP5/YQlXQTMfHI9w== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.3" "@babel/helper-module-transforms@^7.10.1": version "7.10.1" @@ -164,17 +164,17 @@ "@babel/types" "^7.10.1" lodash "^4.17.13" -"@babel/helper-optimise-call-expression@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.1.tgz#b4a1f2561870ce1247ceddb02a3860fa96d72543" - integrity sha512-a0DjNS1prnBsoKx83dP2falChcs7p3i8VMzdrSbfLhuQra/2ENC4sbri34dz/rWmDADsmF1q5GbfaXydh0Jbjg== +"@babel/helper-optimise-call-expression@^7.10.1", "@babel/helper-optimise-call-expression@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.3.tgz#f53c4b6783093195b0f69330439908841660c530" + integrity sha512-kT2R3VBH/cnSz+yChKpaKRJQJWxdGoc6SjioRId2wkeV3bK0wLLioFpJROrX0U4xr/NmxSSAWT/9Ih5snwIIzg== dependencies: - "@babel/types" "^7.10.1" + "@babel/types" "^7.10.3" -"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.8.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.1.tgz#ec5a5cf0eec925b66c60580328b122c01230a127" - integrity sha512-fvoGeXt0bJc7VMWZGCAEBEMo/HAjW2mP8apF5eXK0wSqwLAVHAISCWRoLMBMUs2kqeaG77jltVqu4Hn8Egl3nA== +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.1", "@babel/helper-plugin-utils@^7.10.3", "@babel/helper-plugin-utils@^7.8.0": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.3.tgz#aac45cccf8bc1873b99a85f34bceef3beb5d3244" + integrity sha512-j/+j8NAWUTxOtx4LKHybpSClxHoq6I91DQ/mKgAXn5oNUPIUiGppjPIX3TDtJWPrdfP9Kfl7e4fgVMiQR9VE/g== "@babel/helper-regex@^7.10.1": version "7.10.1" @@ -183,16 +183,16 @@ dependencies: lodash "^4.17.13" -"@babel/helper-remap-async-to-generator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.1.tgz#bad6aaa4ff39ce8d4b82ccaae0bfe0f7dbb5f432" - integrity sha512-RfX1P8HqsfgmJ6CwaXGKMAqbYdlleqglvVtht0HGPMSsy2V6MqLlOJVF/0Qyb/m2ZCi2z3q3+s6Pv7R/dQuZ6A== +"@babel/helper-remap-async-to-generator@^7.10.1", "@babel/helper-remap-async-to-generator@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.10.3.tgz#18564f8a6748be466970195b876e8bba3bccf442" + integrity sha512-sLB7666ARbJUGDO60ZormmhQOyqMX/shKBXZ7fy937s+3ID8gSrneMvKSSb+8xIM5V7Vn6uNVtOY1vIm26XLtA== dependencies: "@babel/helper-annotate-as-pure" "^7.10.1" "@babel/helper-wrap-function" "^7.10.1" - "@babel/template" "^7.10.1" - "@babel/traverse" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/template" "^7.10.3" + "@babel/traverse" "^7.10.3" + "@babel/types" "^7.10.3" "@babel/helper-replace-supers@^7.10.1": version "7.10.1" @@ -219,10 +219,10 @@ dependencies: "@babel/types" "^7.10.1" -"@babel/helper-validator-identifier@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.1.tgz#5770b0c1a826c4f53f5ede5e153163e0318e94b5" - integrity sha512-5vW/JXLALhczRCWP0PnFDMCJAchlBvM7f4uk/jXritBnIa6E1KmqmtrS3yn1LAnxFBypQ3eneLuXjsnfQsgILw== +"@babel/helper-validator-identifier@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.3.tgz#60d9847f98c4cea1b279e005fdb7c28be5412d15" + integrity sha512-bU8JvtlYpJSBPuj1VUmKpFGaDZuLxASky3LhaKj3bmpSTY6VWooSM8msk+Z0CZoErFye2tlABF6yDkT3FOPAXw== "@babel/helper-wrap-function@^7.10.1": version "7.10.1" @@ -243,27 +243,27 @@ "@babel/traverse" "^7.10.1" "@babel/types" "^7.10.1" -"@babel/highlight@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.1.tgz#841d098ba613ba1a427a2b383d79e35552c38ae0" - integrity sha512-8rMof+gVP8mxYZApLF/JgNDAkdKa+aJt3ZYxF8z6+j/hpeXL7iMsKCPHa2jNMHu/qqBwzQF4OHNoYi8dMA/rYg== +"@babel/highlight@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.3.tgz#c633bb34adf07c5c13156692f5922c81ec53f28d" + integrity sha512-Ih9B/u7AtgEnySE2L2F0Xm0GaM729XqqLfHkalTsbjXGyqmf/6M0Cu0WpvqueUlW+xk88BHw9Nkpj49naU+vWw== dependencies: - "@babel/helper-validator-identifier" "^7.10.1" + "@babel/helper-validator-identifier" "^7.10.3" chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.10.1", "@babel/parser@^7.10.2": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.2.tgz#871807f10442b92ff97e4783b9b54f6a0ca812d0" - integrity sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ== +"@babel/parser@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.3.tgz#7e71d892b0d6e7d04a1af4c3c79d72c1f10f5315" + integrity sha512-oJtNJCMFdIMwXGmx+KxuaD7i3b8uS7TTFYW/FNG2BT8m+fmGHoiPYoH0Pe3gya07WuFmM5FCDIr1x0irkD/hyA== -"@babel/plugin-proposal-async-generator-functions@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.1.tgz#6911af5ba2e615c4ff3c497fe2f47b35bf6d7e55" - integrity sha512-vzZE12ZTdB336POZjmpblWfNNRpMSua45EYnRigE2XsZxcXcIyly2ixnTJasJE4Zq3U7t2d8rRF7XRUuzHxbOw== +"@babel/plugin-proposal-async-generator-functions@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.3.tgz#5a02453d46e5362e2073c7278beab2e53ad7d939" + integrity sha512-WUUWM7YTOudF4jZBAJIW9D7aViYC/Fn0Pln4RIHlQALyno3sXSjqmTA4Zy1TKC2D49RCR8Y/Pn4OIUtEypK3CA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/helper-remap-async-to-generator" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/helper-remap-async-to-generator" "^7.10.3" "@babel/plugin-syntax-async-generators" "^7.8.0" "@babel/plugin-proposal-class-properties@^7.10.1": @@ -306,12 +306,12 @@ "@babel/helper-plugin-utils" "^7.10.1" "@babel/plugin-syntax-numeric-separator" "^7.10.1" -"@babel/plugin-proposal-object-rest-spread@^7.10.1", "@babel/plugin-proposal-object-rest-spread@^7.2.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.1.tgz#cba44908ac9f142650b4a65b8aa06bf3478d5fb6" - integrity sha512-Z+Qri55KiQkHh7Fc4BW6o+QBuTagbOp9txE+4U1i79u9oWlf2npkiDx+Rf3iK3lbcHBuNy9UOkwuR5wOMH3LIQ== +"@babel/plugin-proposal-object-rest-spread@^7.10.3", "@babel/plugin-proposal-object-rest-spread@^7.2.0": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.10.3.tgz#b8d0d22f70afa34ad84b7a200ff772f9b9fce474" + integrity sha512-ZZh5leCIlH9lni5bU/wB/UcjtcVLgR8gc+FAgW2OOY+m9h1II3ItTO1/cewNUcsIDZSYcSaz/rYVls+Fb0ExVQ== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" "@babel/plugin-syntax-object-rest-spread" "^7.8.0" "@babel/plugin-transform-parameters" "^7.10.1" @@ -323,12 +323,12 @@ "@babel/helper-plugin-utils" "^7.10.1" "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-optional-chaining@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.1.tgz#15f5d6d22708629451a91be28f8facc55b0e818c" - integrity sha512-dqQj475q8+/avvok72CF3AOSV/SGEcH29zT5hhohqqvvZ2+boQoOr7iGldBG5YXTO2qgCgc2B3WvVLUdbeMlGA== +"@babel/plugin-proposal-optional-chaining@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.10.3.tgz#9a726f94622b653c0a3a7a59cdce94730f526f7c" + integrity sha512-yyG3n9dJ1vZ6v5sfmIlMMZ8azQoqx/5/nZTSWX1td6L1H1bsjzA8TInDChpafCZiJkeOFzp/PtrfigAQXxI1Ng== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" "@babel/plugin-syntax-optional-chaining" "^7.8.0" "@babel/plugin-proposal-private-methods@^7.10.1": @@ -448,26 +448,26 @@ "@babel/helper-plugin-utils" "^7.10.1" lodash "^4.17.13" -"@babel/plugin-transform-classes@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.1.tgz#6e11dd6c4dfae70f540480a4702477ed766d733f" - integrity sha512-P9V0YIh+ln/B3RStPoXpEQ/CoAxQIhRSUn7aXqQ+FZJ2u8+oCtjIXR3+X0vsSD8zv+mb56K7wZW1XiDTDGiDRQ== +"@babel/plugin-transform-classes@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.3.tgz#8d9a656bc3d01f3ff69e1fccb354b0f9d72ac544" + integrity sha512-irEX0ChJLaZVC7FvvRoSIxJlmk0IczFLcwaRXUArBKYHCHbOhe57aG8q3uw/fJsoSXvZhjRX960hyeAGlVBXZw== dependencies: "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-define-map" "^7.10.1" - "@babel/helper-function-name" "^7.10.1" - "@babel/helper-optimise-call-expression" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-define-map" "^7.10.3" + "@babel/helper-function-name" "^7.10.3" + "@babel/helper-optimise-call-expression" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.3" "@babel/helper-replace-supers" "^7.10.1" "@babel/helper-split-export-declaration" "^7.10.1" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.1.tgz#59aa399064429d64dce5cf76ef9b90b7245ebd07" - integrity sha512-mqSrGjp3IefMsXIenBfGcPXxJxweQe2hEIwMQvjtiDQ9b1IBvDUjkAtV/HMXX47/vXf14qDNedXsIiNd1FmkaQ== +"@babel/plugin-transform-computed-properties@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.3.tgz#d3aa6eef67cb967150f76faff20f0abbf553757b" + integrity sha512-GWzhaBOsdbjVFav96drOz7FzrcEW6AP5nax0gLIpstiFaI3LOb2tAg06TimaWU6YKOfUACK3FVrxPJ4GSc5TgA== dependencies: - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" "@babel/plugin-transform-destructuring@^7.10.1": version "7.10.1" @@ -547,14 +547,14 @@ "@babel/helper-simple-access" "^7.10.1" babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-modules-systemjs@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.1.tgz#9962e4b0ac6aaf2e20431ada3d8ec72082cbffb6" - integrity sha512-ewNKcj1TQZDL3YnO85qh9zo1YF1CHgmSTlRQgHqe63oTrMI85cthKtZjAiZSsSNjPQ5NCaYo5QkbYqEw1ZBgZA== +"@babel/plugin-transform-modules-systemjs@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.3.tgz#004ae727b122b7b146b150d50cba5ffbff4ac56b" + integrity sha512-GWXWQMmE1GH4ALc7YXW56BTh/AlzvDWhUNn9ArFF0+Cz5G8esYlVbXfdyHa1xaD1j+GnBoCeoQNlwtZTVdiG/A== dependencies: - "@babel/helper-hoist-variables" "^7.10.1" + "@babel/helper-hoist-variables" "^7.10.3" "@babel/helper-module-transforms" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" babel-plugin-dynamic-import-node "^2.3.3" "@babel/plugin-transform-modules-umd@^7.10.1": @@ -565,10 +565,10 @@ "@babel/helper-module-transforms" "^7.10.1" "@babel/helper-plugin-utils" "^7.10.1" -"@babel/plugin-transform-named-capturing-groups-regex@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.8.3.tgz#a2a72bffa202ac0e2d0506afd0939c5ecbc48c6c" - integrity sha512-f+tF/8UVPU86TrCb06JoPWIdDpTNSGGcAtaD9mLP0aYGA0OS0j7j7DHJR0GTFrUZPUU6loZhbsVZgTh0N+Qdnw== +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.3.tgz#a4f8444d1c5a46f35834a410285f2c901c007ca6" + integrity sha512-I3EH+RMFyVi8Iy/LekQm948Z4Lz4yKT7rK+vuCAeRm0kTa6Z5W7xuhRxDNJv0FPya/her6AUgrDITb70YHtTvA== dependencies: "@babel/helper-create-regexp-features-plugin" "^7.8.3" @@ -602,10 +602,10 @@ dependencies: "@babel/helper-plugin-utils" "^7.10.1" -"@babel/plugin-transform-regenerator@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.1.tgz#10e175cbe7bdb63cc9b39f9b3f823c5c7c5c5490" - integrity sha512-B3+Y2prScgJ2Bh/2l9LJxKbb8C8kRfsG4AdPT+n7ixBHIxJaIG8bi8tgjxUMege1+WqSJ+7gu1YeoMVO3gPWzw== +"@babel/plugin-transform-regenerator@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.3.tgz#6ec680f140a5ceefd291c221cb7131f6d7e8cb6d" + integrity sha512-H5kNeW0u8mbk0qa1jVIVTeJJL6/TJ81ltD4oyPx0P499DhMJrTmmIFCmJ3QloGpQG8K9symccB7S7SJpCKLwtw== dependencies: regenerator-transform "^0.14.2" @@ -617,12 +617,12 @@ "@babel/helper-plugin-utils" "^7.10.1" "@babel/plugin-transform-runtime@^7.2.0": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.1.tgz#fd1887f749637fb2ed86dc278e79eb41df37f4b1" - integrity sha512-4w2tcglDVEwXJ5qxsY++DgWQdNJcCCsPxfT34wCUwIf2E7dI7pMpH8JczkMBbgBTNzBX62SZlNJ9H+De6Zebaw== + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.10.3.tgz#3b287b06acc534a7cb6e6c71d6b1d88b1922dd6c" + integrity sha512-b5OzMD1Hi8BBzgQdRHyVVaYrk9zG0wset1it2o3BgonkPadXfOv0aXRqd7864DeOIu3FGKP/h6lr15FE5mahVw== dependencies: - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-module-imports" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.3" resolve "^1.8.1" semver "^5.5.1" @@ -648,13 +648,13 @@ "@babel/helper-plugin-utils" "^7.10.1" "@babel/helper-regex" "^7.10.1" -"@babel/plugin-transform-template-literals@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.1.tgz#914c7b7f4752c570ea00553b4284dad8070e8628" - integrity sha512-t7B/3MQf5M1T9hPCRG28DNGZUuxAuDqLYS03rJrIk2prj/UV7Z6FOneijhQhnv/Xa039vidXeVbvjK2SK5f7Gg== +"@babel/plugin-transform-template-literals@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.3.tgz#69d39b3d44b31e7b4864173322565894ce939b25" + integrity sha512-yaBn9OpxQra/bk0/CaA4wr41O0/Whkg6nqjqApcinxM7pro51ojhX6fv1pimAnVjVfDy14K0ULoRL70CA9jWWA== dependencies: "@babel/helper-annotate-as-pure" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" + "@babel/helper-plugin-utils" "^7.10.3" "@babel/plugin-transform-typeof-symbol@^7.10.1": version "7.10.1" @@ -679,23 +679,23 @@ "@babel/helper-plugin-utils" "^7.10.1" "@babel/preset-env@^7.2.0": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.2.tgz#715930f2cf8573b0928005ee562bed52fb65fdfb" - integrity sha512-MjqhX0RZaEgK/KueRzh+3yPSk30oqDKJ5HP5tqTSB1e2gzGS3PLy7K0BIpnp78+0anFuSwOeuCf1zZO7RzRvEA== + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.10.3.tgz#3e58c9861bbd93b6a679987c7e4bd365c56c80c9" + integrity sha512-jHaSUgiewTmly88bJtMHbOd1bJf2ocYxb5BWKSDQIP5tmgFuS/n0gl+nhSrYDhT33m0vPxp+rP8oYYgPgMNQlg== dependencies: - "@babel/compat-data" "^7.10.1" + "@babel/compat-data" "^7.10.3" "@babel/helper-compilation-targets" "^7.10.2" - "@babel/helper-module-imports" "^7.10.1" - "@babel/helper-plugin-utils" "^7.10.1" - "@babel/plugin-proposal-async-generator-functions" "^7.10.1" + "@babel/helper-module-imports" "^7.10.3" + "@babel/helper-plugin-utils" "^7.10.3" + "@babel/plugin-proposal-async-generator-functions" "^7.10.3" "@babel/plugin-proposal-class-properties" "^7.10.1" "@babel/plugin-proposal-dynamic-import" "^7.10.1" "@babel/plugin-proposal-json-strings" "^7.10.1" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.1" "@babel/plugin-proposal-numeric-separator" "^7.10.1" - "@babel/plugin-proposal-object-rest-spread" "^7.10.1" + "@babel/plugin-proposal-object-rest-spread" "^7.10.3" "@babel/plugin-proposal-optional-catch-binding" "^7.10.1" - "@babel/plugin-proposal-optional-chaining" "^7.10.1" + "@babel/plugin-proposal-optional-chaining" "^7.10.3" "@babel/plugin-proposal-private-methods" "^7.10.1" "@babel/plugin-proposal-unicode-property-regex" "^7.10.1" "@babel/plugin-syntax-async-generators" "^7.8.0" @@ -712,8 +712,8 @@ "@babel/plugin-transform-async-to-generator" "^7.10.1" "@babel/plugin-transform-block-scoped-functions" "^7.10.1" "@babel/plugin-transform-block-scoping" "^7.10.1" - "@babel/plugin-transform-classes" "^7.10.1" - "@babel/plugin-transform-computed-properties" "^7.10.1" + "@babel/plugin-transform-classes" "^7.10.3" + "@babel/plugin-transform-computed-properties" "^7.10.3" "@babel/plugin-transform-destructuring" "^7.10.1" "@babel/plugin-transform-dotall-regex" "^7.10.1" "@babel/plugin-transform-duplicate-keys" "^7.10.1" @@ -724,24 +724,24 @@ "@babel/plugin-transform-member-expression-literals" "^7.10.1" "@babel/plugin-transform-modules-amd" "^7.10.1" "@babel/plugin-transform-modules-commonjs" "^7.10.1" - "@babel/plugin-transform-modules-systemjs" "^7.10.1" + "@babel/plugin-transform-modules-systemjs" "^7.10.3" "@babel/plugin-transform-modules-umd" "^7.10.1" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.8.3" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.3" "@babel/plugin-transform-new-target" "^7.10.1" "@babel/plugin-transform-object-super" "^7.10.1" "@babel/plugin-transform-parameters" "^7.10.1" "@babel/plugin-transform-property-literals" "^7.10.1" - "@babel/plugin-transform-regenerator" "^7.10.1" + "@babel/plugin-transform-regenerator" "^7.10.3" "@babel/plugin-transform-reserved-words" "^7.10.1" "@babel/plugin-transform-shorthand-properties" "^7.10.1" "@babel/plugin-transform-spread" "^7.10.1" "@babel/plugin-transform-sticky-regex" "^7.10.1" - "@babel/plugin-transform-template-literals" "^7.10.1" + "@babel/plugin-transform-template-literals" "^7.10.3" "@babel/plugin-transform-typeof-symbol" "^7.10.1" "@babel/plugin-transform-unicode-escapes" "^7.10.1" "@babel/plugin-transform-unicode-regex" "^7.10.1" "@babel/preset-modules" "^0.1.3" - "@babel/types" "^7.10.2" + "@babel/types" "^7.10.3" browserslist "^4.12.0" core-js-compat "^3.6.2" invariant "^2.2.2" @@ -760,42 +760,42 @@ esutils "^2.0.2" "@babel/runtime@^7.2.0", "@babel/runtime@^7.8.4": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.2.tgz#d103f21f2602497d38348a32e008637d506db839" - integrity sha512-6sF3uQw2ivImfVIl62RZ7MXhO2tap69WeWK57vAaimT6AZbE4FbqjdEJIN1UqoD6wI6B+1n9UiagafH1sxjOtg== + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.10.3.tgz#670d002655a7c366540c67f6fd3342cd09500364" + integrity sha512-RzGO0RLSdokm9Ipe/YD+7ww8X2Ro79qiXZF3HU9ljrM+qnJmH1Vqth+hbiQZy761LnMJTMitHDuKVYTk3k4dLw== dependencies: regenerator-runtime "^0.13.4" -"@babel/template@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.1.tgz#e167154a94cb5f14b28dc58f5356d2162f539811" - integrity sha512-OQDg6SqvFSsc9A0ej6SKINWrpJiNonRIniYondK2ViKhB06i3c0s+76XUft71iqBEe9S1OKsHwPAjfHnuvnCig== +"@babel/template@^7.10.1", "@babel/template@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.3.tgz#4d13bc8e30bf95b0ce9d175d30306f42a2c9a7b8" + integrity sha512-5BjI4gdtD+9fHZUsaxPHPNpwa+xRkDO7c7JbhYn2afvrkDu5SfAAbi9AIMXw2xEhO/BR35TqiW97IqNvCo/GqA== dependencies: - "@babel/code-frame" "^7.10.1" - "@babel/parser" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/code-frame" "^7.10.3" + "@babel/parser" "^7.10.3" + "@babel/types" "^7.10.3" -"@babel/traverse@^7.10.1": - version "7.10.1" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.1.tgz#bbcef3031e4152a6c0b50147f4958df54ca0dd27" - integrity sha512-C/cTuXeKt85K+p08jN6vMDz8vSV0vZcI0wmQ36o6mjbuo++kPMdpOYw23W2XH04dbRt9/nMEfA4W3eR21CD+TQ== +"@babel/traverse@^7.10.1", "@babel/traverse@^7.10.3": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.10.3.tgz#0b01731794aa7b77b214bcd96661f18281155d7e" + integrity sha512-qO6623eBFhuPm0TmmrUFMT1FulCmsSeJuVGhiLodk2raUDFhhTECLd9E9jC4LBIWziqt4wgF6KuXE4d+Jz9yug== dependencies: - "@babel/code-frame" "^7.10.1" - "@babel/generator" "^7.10.1" - "@babel/helper-function-name" "^7.10.1" + "@babel/code-frame" "^7.10.3" + "@babel/generator" "^7.10.3" + "@babel/helper-function-name" "^7.10.3" "@babel/helper-split-export-declaration" "^7.10.1" - "@babel/parser" "^7.10.1" - "@babel/types" "^7.10.1" + "@babel/parser" "^7.10.3" + "@babel/types" "^7.10.3" debug "^4.1.0" globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.10.1", "@babel/types@^7.10.2", "@babel/types@^7.4.4": - version "7.10.2" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.2.tgz#30283be31cad0dbf6fb00bd40641ca0ea675172d" - integrity sha512-AD3AwWBSz0AWF0AkCN9VPiWrvldXq+/e3cHa4J89vo4ymjz1XwrBFFVZmkJTsQIPNk+ZVomPSXUJqq8yyjZsng== +"@babel/types@^7.10.1", "@babel/types@^7.10.3", "@babel/types@^7.4.4": + version "7.10.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.10.3.tgz#6535e3b79fea86a6b09e012ea8528f935099de8e" + integrity sha512-nZxaJhBXBQ8HVoIcGsf9qWep3Oh3jCENK54V4mRF7qaJabVsAYdbTtmSD8WmAp1R6ytPiu5apMwSXyxB1WlaBA== dependencies: - "@babel/helper-validator-identifier" "^7.10.1" + "@babel/helper-validator-identifier" "^7.10.3" lodash "^4.17.13" to-fast-properties "^2.0.0" @@ -828,9 +828,9 @@ "@types/node" "*" "@types/json-schema@^7.0.4": - version "7.0.4" - resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.4.tgz#38fd73ddfd9b55abb1e1b2ed578cb55bd7b7d339" - integrity sha512-8+KAKzEvSUdeo+kmqnKrqgeE+LcA0tjYWFY7RPProVYwnqDjukzO+3b6dLD56rYX5TdWejnEOLJYOIeh4CXKuA== + version "7.0.5" + resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd" + integrity sha512-7+2BITlgjgDhH0vvwZU/HZJVyk+2XUlvxXe8dFMedNX/aMkaOq++rMAFXc0tM7ij15QaWlbdQASBR9dihi+bDQ== "@types/minimatch@*": version "3.0.3" @@ -838,9 +838,9 @@ integrity sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA== "@types/node@*": - version "14.0.11" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.11.tgz#61d4886e2424da73b7b25547f59fdcb534c165a3" - integrity sha512-lCvvI24L21ZVeIiyIUHZ5Oflv1hhHQ5E1S25IRlKIXaRkVgmXpJMI3wUJkmym2bTbCe+WoIibQnMVAU3FguaOg== + version "14.0.13" + resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.13.tgz#ee1128e881b874c371374c1f72201893616417c9" + integrity sha512-rouEWBImiRaSJsVA+ITTFM6ZxibuAlTuNOCyxVbwreu6k6+ujs7DfnU9o+PShFhET78pMBl3eH+AGSI5eOTkPA== "@types/q@^1.5.1": version "1.5.4" @@ -1045,9 +1045,9 @@ ajv-errors@^1.0.0: integrity sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ== ajv-keywords@^3.1.0, ajv-keywords@^3.4.1: - version "3.4.1" - resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.4.1.tgz#ef916e271c64ac12171fd8384eaae6b2345854da" - integrity sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ== + version "3.5.0" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-3.5.0.tgz#5c894537098785926d71e696114a53ce768ed773" + integrity sha512-eyoaac3btgU8eJlvh01En8OCKzRqlLe2G5jDsCr3RiE2uLGMEEB1aaGwVVpwR8M95956tGH6R+9edC++OvzaVw== ajv@^6.1.0, ajv@^6.10.2, ajv@^6.12.2: version "6.12.2" @@ -1226,16 +1226,16 @@ atob@^2.1.2: integrity sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg== autoprefixer@^9.4.2: - version "9.8.0" - resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.0.tgz#68e2d2bef7ba4c3a65436f662d0a56a741e56511" - integrity sha512-D96ZiIHXbDmU02dBaemyAg53ez+6F5yZmapmgKcjm35yEe1uVDYI8hGW3VYoGRaG290ZFf91YxHrR518vC0u/A== + version "9.8.2" + resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.2.tgz#7347396ee576b18687041bfbacd76d78e27baa56" + integrity sha512-9UwMMU8Rg7Fj0c55mbOpXrr/2WrRqoOwOlLNTyyYt+nhiyQdIBWipp5XWzt+Lge8r3DK5y+EHMc1OBf8VpZA6Q== dependencies: browserslist "^4.12.0" - caniuse-lite "^1.0.30001061" - chalk "^2.4.2" + caniuse-lite "^1.0.30001084" + kleur "^4.0.1" normalize-range "^0.1.2" num2fraction "^1.2.2" - postcss "^7.0.30" + postcss "^7.0.32" postcss-value-parser "^4.1.0" axios@^0.18.1: @@ -1638,19 +1638,10 @@ caniuse-api@^3.0.0: lodash.memoize "^4.1.2" lodash.uniq "^4.5.0" -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001061: - version "1.0.30001078" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001078.tgz#e1b6e2ae327b6a1ec11f65ec7a0dde1e7093074c" - integrity sha512-sF12qXe9VMm32IEf/+NDvmTpwJaaU7N1igpiH2FdI4DyABJSsOqG3ZAcFvszLkoLoo1y6VJLMYivukUAxaMASw== - -chalk@2.4.2, chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: - version "2.4.2" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" - integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== - dependencies: - ansi-styles "^3.2.1" - escape-string-regexp "^1.0.5" - supports-color "^5.3.0" +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001043, caniuse-lite@^1.0.30001084: + version "1.0.30001085" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001085.tgz#bed28bd51ff7425d33ee23e730c7f3b703711db6" + integrity sha512-x0YRFRE0pmOD90z+9Xk7jwO58p4feVNXP+U8kWV+Uo/HADyrgESlepzIkUqPgaXkpyceZU6siM1gsK7sHgplqA== chalk@^1.1.3: version "1.1.3" @@ -1663,6 +1654,15 @@ chalk@^1.1.3: strip-ansi "^3.0.0" supports-color "^2.0.0" +chalk@^2.0.0, chalk@^2.4.1, chalk@^2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424" + integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ== + dependencies: + ansi-styles "^3.2.1" + escape-string-regexp "^1.0.5" + supports-color "^5.3.0" + charenc@~0.0.1: version "0.0.2" resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667" @@ -2018,7 +2018,7 @@ cross-env@^5.1: dependencies: cross-spawn "^6.0.5" -cross-spawn@6.0.5, cross-spawn@^6.0.0, cross-spawn@^6.0.5: +cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ== @@ -2231,7 +2231,7 @@ debug@=3.1.0: dependencies: ms "2.0.0" -debug@^3.0.0, debug@^3.1.1, debug@^3.2.5: +debug@^3.1.1, debug@^3.2.5: version "3.2.6" resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b" integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ== @@ -2451,14 +2451,14 @@ ee-first@1.1.1: integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= electron-to-chromium@^1.3.413: - version "1.3.463" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.463.tgz#bae89d8c2c69b4be32f80221fe49ab5786fab368" - integrity sha512-mAqvpG0efJXV9BGXPVjFdBFiqmawGoIc+c8T2uXYEvbV1/261PaOT0EzZ9dKW4IdGiHXQGSKnnOU86QhJ+5JcA== + version "1.3.480" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.480.tgz#190ae45074578349a4c4f336fba29e76b20e9ef5" + integrity sha512-wnuUfQCBMAdzu5Xe+F4FjaRK+6ToG6WvwG72s8k/3E6b+hoGVYGiQE7JD1NhiCMcqF3+wV+c2vAnaLGRSSWVqA== elliptic@^6.0.0, elliptic@^6.5.2: - version "6.5.2" - resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.2.tgz#05c5678d7173c049d8ca433552224a495d0e3762" - integrity sha512-f4x70okzZbIQl/NSRLkI/+tteV/9WqL98zx+SQ69KbXxmVrmjwsNUPn/gYJJ0sHvEak24cZgHIPegRePAtA/xw== + version "6.5.3" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.3.tgz#cb59eb2efdaf73a0bd78ccd7015a62ad6e0f93d6" + integrity sha512-IMqzv5wNQf+E6aHeIqATs0tOLeOTwj1QKbRcS3jBbYkl5oLAserA8yJTT7/VyHUYG91PRmPyeQDObKLPpeS4dw== dependencies: bn.js "^4.4.0" brorand "^1.0.1" @@ -2473,11 +2473,6 @@ emoji-regex@^7.0.1: resolved "https://registry.yarnpkg.com/emoji-regex/-/emoji-regex-7.0.3.tgz#933a04052860c85e83c122479c4748a8e4c72156" integrity sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA== -emojis-list@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" - integrity sha1-TapNnbAPmBmIDHn6RXrlsJof04k= - emojis-list@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-3.0.0.tgz#5570662046ad29e2e916e71aae260abdff4f6a78" @@ -2495,19 +2490,10 @@ end-of-stream@^1.0.0, end-of-stream@^1.1.0: dependencies: once "^1.4.0" -enhanced-resolve@4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz#41c7e0bfdfe74ac1ffe1e57ad6a5c6c9f3742a7f" - integrity sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng== - dependencies: - graceful-fs "^4.1.2" - memory-fs "^0.4.0" - tapable "^1.0.0" - -enhanced-resolve@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.1.1.tgz#2937e2b8066cd0fe7ce0990a98f0d71a35189f66" - integrity sha512-98p2zE+rL7/g/DzMHMTF4zZlCgeVdJ7yr6xzEpJRYwFYrGi9ANdn5DnJURg6RpBkyk60XYDnWIv51VfIhfNGuA== +enhanced-resolve@^4.1.0, enhanced-resolve@^4.1.1: + version "4.2.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-4.2.0.tgz#5d43bda4a0fd447cb0ebbe71bef8deff8805ad0d" + integrity sha512-S7eiFb/erugyd1rLb6mQ3Vuq+EXHv5cpCkNqqIkYkBgN2QdFnyCZzFBleqwGEx4lgNGYij81BWnCrFNK7vxvjQ== dependencies: graceful-fs "^4.1.2" memory-fs "^0.5.0" @@ -2540,21 +2526,21 @@ error-stack-parser@^2.0.0: stackframe "^1.1.1" es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5: - version "1.17.5" - resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.5.tgz#d8c9d1d66c8981fb9200e2251d799eee92774ae9" - integrity sha512-BR9auzDbySxOcfog0tLECW8l28eRGpDpU3Dm3Hp4q/N+VtLTmyj4EUN088XZWQDW/hzj6sYRDXeOFsaAODKvpg== + version "1.17.6" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a" + integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw== dependencies: es-to-primitive "^1.2.1" function-bind "^1.1.1" has "^1.0.3" has-symbols "^1.0.1" - is-callable "^1.1.5" - is-regex "^1.0.5" + is-callable "^1.2.0" + is-regex "^1.1.0" object-inspect "^1.7.0" object-keys "^1.1.1" object.assign "^4.1.0" - string.prototype.trimleft "^2.1.1" - string.prototype.trimright "^2.1.1" + string.prototype.trimend "^1.0.1" + string.prototype.trimstart "^1.0.1" es-to-primitive@^1.2.1: version "1.2.1" @@ -2757,9 +2743,9 @@ extract-text-webpack-plugin@v4.0.0-beta.0: webpack-sources "^1.1.0" fast-deep-equal@^3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.1.tgz#545145077c501491e33b15ec408c294376e94ae4" - integrity sha512-8UEa58QDLauDNfpbrX55Q9jrGHThw2ZMdOky5Gl1CDtVeJDPVrG4Jxx1N8jw2gkWaff5UUuX1KJd+9zGe2B+ZA== + version "3.1.3" + resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525" + integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== fast-glob@^2.0.2: version "2.2.7" @@ -2890,7 +2876,7 @@ find-up@^4.0.0: locate-path "^5.0.0" path-exists "^4.0.0" -findup-sync@3.0.0: +findup-sync@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== @@ -2916,11 +2902,9 @@ follow-redirects@1.5.10: debug "=3.1.0" follow-redirects@^1.0.0: - version "1.11.0" - resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.11.0.tgz#afa14f08ba12a52963140fe43212658897bc0ecb" - integrity sha512-KZm0V+ll8PfBrKwMzdo5D13b1bur9Iq9Zd/RMmAoQQcl2PxxFml8cxXPaaPYVbV0RjNjq1CU7zIzAOqtUPudmA== - dependencies: - debug "^3.0.0" + version "1.12.1" + resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.12.1.tgz#de54a6205311b93d60398ebc01cf7015682312b6" + integrity sha512-tmRv0AVuR7ZyouUHLeNSiO6pqulF7dYa3s19c6t+wz9LD69/uSzdMxJ2S91nTI9U3rt/IldxpzMOFejp6f0hjg== font-awesome@^4.7.0: version "4.7.0" @@ -3074,13 +3058,6 @@ glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4: once "^1.3.0" path-is-absolute "^1.0.0" -global-modules@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" - integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== - dependencies: - global-prefix "^3.0.0" - global-modules@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-1.0.0.tgz#6d770f0eb523ac78164d72b5e71a8877265cc3ea" @@ -3090,6 +3067,13 @@ global-modules@^1.0.0: is-windows "^1.0.1" resolve-dir "^1.0.0" +global-modules@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/global-modules/-/global-modules-2.0.0.tgz#997605ad2345f27f51539bea26574421215c7780" + integrity sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A== + dependencies: + global-prefix "^3.0.0" + global-prefix@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/global-prefix/-/global-prefix-1.0.2.tgz#dbf743c6c14992593c655568cb66ed32c0122ebe" @@ -3464,7 +3448,7 @@ import-from@^2.1.0: dependencies: resolve-from "^3.0.0" -import-local@2.0.0, import-local@^2.0.0: +import-local@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/import-local/-/import-local-2.0.0.tgz#55070be38a5993cf18ef6db7e961f5bee5c5a09d" integrity sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ== @@ -3528,10 +3512,10 @@ internal-ip@^4.3.0: default-gateway "^4.2.0" ipaddr.js "^1.9.0" -interpret@1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.2.0.tgz#d5061a6224be58e8083985f5014d844359576296" - integrity sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw== +interpret@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" + integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" @@ -3623,7 +3607,7 @@ is-buffer@^2.0.2: resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-2.0.4.tgz#3e572f23c8411a5cfd9557c849e3665e0b290623" integrity sha512-Kq1rokWXOPXWuaMAqZiJW4XxsmD9zGx9q4aePabbn3qCRGedtH7Cm+zV8WETitMfu1wdh+Rvd6w5egwSngUX2A== -is-callable@^1.1.4, is-callable@^1.1.5: +is-callable@^1.1.4, is-callable@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb" integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw== @@ -3768,7 +3752,7 @@ is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-regex@^1.0.4, is-regex@^1.0.5: +is-regex@^1.0.4, is-regex@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff" integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw== @@ -3937,6 +3921,11 @@ kind-of@^6.0.0, kind-of@^6.0.2: resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.3.tgz#07c05034a6c349fa06e24fa35aa76db4580ce4dd" integrity sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw== +kleur@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-4.0.1.tgz#3d4948534b666e2578f93b6fafb62108e64f05ef" + integrity sha512-Qs6SqCLm63rd0kNVh+wO4XsWLU6kgfwwaPYsLiClWf0Tewkzsa6MvB21bespb8cz+ANS+2t3So1ge3gintzhlw== + laravel-mix@^5.0: version "5.0.4" resolved "https://registry.yarnpkg.com/laravel-mix/-/laravel-mix-5.0.4.tgz#606a28781b936d66cf96a0d631909cea22ebf0a8" @@ -4013,15 +4002,6 @@ loader-runner@^2.4.0: resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.4.0.tgz#ed47066bfe534d7e84c4c7b9998c2a75607d9357" integrity sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw== -loader-utils@1.2.3: - version "1.2.3" - resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.2.3.tgz#1ff5dc6911c9f0a062531a4c04b609406108c2c7" - integrity sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA== - dependencies: - big.js "^5.2.2" - emojis-list "^2.0.0" - json5 "^1.0.1" - loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" @@ -4184,7 +4164,7 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" -memory-fs@^0.4.0, memory-fs@^0.4.1: +memory-fs@^0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" integrity sha1-OpoguEYlI+RHz7x+i7gO1me/xVI= @@ -4557,9 +4537,9 @@ object-copy@^0.1.0: kind-of "^3.0.3" object-inspect@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67" - integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw== + version "1.8.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0" + integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA== object-is@^1.0.1: version "1.1.2" @@ -4674,7 +4654,7 @@ os-browserify@^0.3.0: resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.3.0.tgz#854373c7f5c2315914fc9bfc6bd8238fdda1ec27" integrity sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc= -os-locale@^3.0.0, os-locale@^3.1.0: +os-locale@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-3.1.0.tgz#a802a6ee17f24c10483ab9935719cef4ed16bf1a" integrity sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q== @@ -5286,7 +5266,7 @@ postcss@^6.0.1, postcss@^6.0.23: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.27, postcss@^7.0.30: +postcss@^7.0.0, postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.27, postcss@^7.0.32: version "7.0.32" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.32.tgz#4310d6ee347053da3433db2be492883d62cec59d" integrity sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw== @@ -6099,7 +6079,7 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string.prototype.trimend@^1.0.0: +string.prototype.trimend@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913" integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g== @@ -6107,25 +6087,7 @@ string.prototype.trimend@^1.0.0: define-properties "^1.1.3" es-abstract "^1.17.5" -string.prototype.trimleft@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.2.tgz#4408aa2e5d6ddd0c9a80739b087fbc067c03b3cc" - integrity sha512-gCA0tza1JBvqr3bfAIFJGqfdRTyPae82+KTnm3coDXkZN9wnuW3HjGgN386D7hfv5CHQYCI022/rJPVlqXyHSw== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string.prototype.trimstart "^1.0.0" - -string.prototype.trimright@^2.1.1: - version "2.1.2" - resolved "https://registry.yarnpkg.com/string.prototype.trimright/-/string.prototype.trimright-2.1.2.tgz#c76f1cef30f21bbad8afeb8db1511496cfb0f2a3" - integrity sha512-ZNRQ7sY3KroTaYjRS6EbNiiHrOkjihL9aQE/8gfQ4DtAC/aEBRHFJa44OmoWxGGqXuJlfKkZW4WcXErGr+9ZFg== - dependencies: - define-properties "^1.1.3" - es-abstract "^1.17.5" - string.prototype.trimend "^1.0.0" - -string.prototype.trimstart@^1.0.0: +string.prototype.trimstart@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54" integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw== @@ -6190,13 +6152,6 @@ stylehacks@^4.0.0: postcss "^7.0.0" postcss-selector-parser "^3.0.0" -supports-color@6.1.0, supports-color@^6.1.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" - integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== - dependencies: - has-flag "^3.0.0" - supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" @@ -6209,6 +6164,13 @@ supports-color@^5.3.0, supports-color@^5.4.0: dependencies: has-flag "^3.0.0" +supports-color@^6.1.0: + version "6.1.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-6.1.0.tgz#0764abc69c63d5ac842dd4867e8d025e880df8f3" + integrity sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ== + dependencies: + has-flag "^3.0.0" + supports-color@^7.0.0: version "7.1.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.1.0.tgz#68e32591df73e25ad1c4b49108a2ec507962bfd1" @@ -6280,9 +6242,9 @@ terser@^3.11.0: source-map-support "~0.5.10" terser@^4.1.2, terser@^4.6.12: - version "4.7.0" - resolved "https://registry.yarnpkg.com/terser/-/terser-4.7.0.tgz#15852cf1a08e3256a80428e865a2fa893ffba006" - integrity sha512-Lfb0RiZcjRDXCC3OSHJpEkxJ9Qeqs6mp2v4jf2MHfy8vGERmVDuvjXdd/EnP5Deme5F2yBRBymKmKHCBg2echw== + version "4.8.0" + resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" + integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== dependencies: commander "^2.20.0" source-map "~0.6.1" @@ -6565,10 +6527,10 @@ uuid@^3.3.2, uuid@^3.4.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -v8-compile-cache@2.0.3: - version "2.0.3" - resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz#00f7494d2ae2b688cfe2899df6ed2c54bef91dbe" - integrity sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w== +v8-compile-cache@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.1.1.tgz#54bc3cdd43317bca91e35dcaf305b1a7237de745" + integrity sha512-8OQ9CL+VWyt3JStj7HX7/ciTL2V3Rl1Wf5OL+SNTm0yK1KvtReVulksyeRnCANHHuUxHlQig+JJDlUhBt1NQDQ== vary@~1.1.2: version "1.1.2" @@ -6596,9 +6558,9 @@ vue-hot-reload-api@^2.3.0: integrity sha512-BXq3jwIagosjgNVae6tkHzzIk6a8MHFtzAdwhnV5VlvPTFxDCvIttgSiHWjdGoTJvXtmRu5HacExfdarRcFhog== vue-i18n@^8.15: - version "8.18.1" - resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.18.1.tgz#2e683ac93a15617bdcd210f99359d6034e8425dd" - integrity sha512-K+hFQJksF8Ph23pnhbwSyoQx+4Y1q/rh2o7GiXI/3rLCCrwanUbzudC8+trp0Mb8rn9y83DYF6RXNrMd+VsuCw== + version "8.18.2" + resolved "https://registry.yarnpkg.com/vue-i18n/-/vue-i18n-8.18.2.tgz#cd7c12f2e178e6faa23b0e3cfd2f7bac9305f8fc" + integrity sha512-0X5nBTCZAVjlwcrPaYJwNs3iipBBTv0AUHwQUOa8yP3XbQGWKbRHqBb3OhCYtum/IHDD21d/df5Xd2VgyxbxfA== vue-loader@^15.4.2: version "15.9.2" @@ -6663,21 +6625,21 @@ wbuf@^1.1.0, wbuf@^1.7.3: minimalistic-assert "^1.0.0" webpack-cli@^3.1.2: - version "3.3.11" - resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.11.tgz#3bf21889bf597b5d82c38f215135a411edfdc631" - integrity sha512-dXlfuml7xvAFwYUPsrtQAA9e4DOe58gnzSxhgrO/ZM/gyXTBowrsYeubyN4mqGhYdpXMFNyQ6emjJS9M7OBd4g== + version "3.3.12" + resolved "https://registry.yarnpkg.com/webpack-cli/-/webpack-cli-3.3.12.tgz#94e9ada081453cd0aa609c99e500012fd3ad2d4a" + integrity sha512-NVWBaz9k839ZH/sinurM+HcDvJOTXwSjYp1ku+5XKeOC03z8v5QitnK/x+lAxGXFyhdayoIf/GOpv85z3/xPag== dependencies: - chalk "2.4.2" - cross-spawn "6.0.5" - enhanced-resolve "4.1.0" - findup-sync "3.0.0" - global-modules "2.0.0" - import-local "2.0.0" - interpret "1.2.0" - loader-utils "1.2.3" - supports-color "6.1.0" - v8-compile-cache "2.0.3" - yargs "13.2.4" + chalk "^2.4.2" + cross-spawn "^6.0.5" + enhanced-resolve "^4.1.1" + findup-sync "^3.0.0" + global-modules "^2.0.0" + import-local "^2.0.0" + interpret "^1.4.0" + loader-utils "^1.4.0" + supports-color "^6.1.0" + v8-compile-cache "^2.1.1" + yargs "^13.3.2" webpack-dev-middleware@^3.7.2: version "3.7.2" @@ -6892,7 +6854,7 @@ yargs-parser@^11.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^13.1.0, yargs-parser@^13.1.2: +yargs-parser@^13.1.2: version "13.1.2" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-13.1.2.tgz#130f09702ebaeef2650d54ce6e3e5706f7a4fb38" integrity sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg== @@ -6900,23 +6862,6 @@ yargs-parser@^13.1.0, yargs-parser@^13.1.2: camelcase "^5.0.0" decamelize "^1.2.0" -yargs@13.2.4: - version "13.2.4" - resolved "https://registry.yarnpkg.com/yargs/-/yargs-13.2.4.tgz#0b562b794016eb9651b98bd37acf364aa5d6dc83" - integrity sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg== - dependencies: - cliui "^5.0.0" - find-up "^3.0.0" - get-caller-file "^2.0.1" - os-locale "^3.1.0" - require-directory "^2.1.1" - require-main-filename "^2.0.0" - set-blocking "^2.0.0" - string-width "^3.0.0" - which-module "^2.0.0" - y18n "^4.0.0" - yargs-parser "^13.1.0" - yargs@^12.0.5: version "12.0.5" resolved "https://registry.yarnpkg.com/yargs/-/yargs-12.0.5.tgz#05f5997b609647b64f66b81e3b4b10a368e7ad13"