From 31f77c5cebaf8684d2e51c2d5f5e5fdbb1b2ccf8 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Fri, 3 Jul 2026 22:42:27 +0200 Subject: [PATCH 01/12] Modernize test tooling and add static analysis config MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replaces the abandoned christophwurst/nextcloud dev stub with nextcloud/ocp so PHPUnit and PHPStan can resolve OCP types without a live Nextcloud install. Modernizes tests/Unit/Controller/PageControllerTest.php to PHPUnit\Framework\TestCase / setUp(): void and fixes it to match PageController's actual constructor (IUserSession, not a raw user id string) — it was silently stale. tests/bootstrap.php now just loads Composer's autoloader; the old full-server bootstrap moves to tests/bootstrap.integration.php for the (still server-dependent) integration suite, which gets its own `make test-integration` target since `make test` previously installed deps with --no-dev and would have stripped PHPUnit itself. Adds a PHPStan config (level 3) with a baseline freezing the 237 pre-existing findings (missing Doctrine DBAL stub types, plus a runtime class_alias() static analysis can't see through — mirrored in tests/phpstan-bootstrap.php) so analysis starts green and only flags newly introduced issues. Verified: make test, composer run lint, composer run phpstan, and composer run test:unit all pass on PHP 8.2, 8.3, and 8.5. Co-Authored-By: Claude Sonnet 5 --- .gitignore | 2 + Makefile | 17 +- composer.json | 24 +- composer.lock | 2045 +++++++++++++++++- phpstan-baseline.neon | 426 ++++ phpstan.neon | 12 + phpunit.integration.xml | 2 +- tests/Integration/AppTest.php | 4 +- tests/Unit/Controller/PageControllerTest.php | 24 +- tests/bootstrap.integration.php | 15 + tests/bootstrap.php | 14 +- tests/phpstan-bootstrap.php | 12 + 12 files changed, 2489 insertions(+), 108 deletions(-) create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon create mode 100644 tests/bootstrap.integration.php create mode 100644 tests/phpstan-bootstrap.php diff --git a/.gitignore b/.gitignore index fc85e3b..4c48d12 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ js/dist/ js/node_modules/ +vendor/ +.phpunit.result.cache diff --git a/Makefile b/Makefile index 58eeb0f..718aed9 100644 --- a/Makefile +++ b/Makefile @@ -159,7 +159,22 @@ appstore: --exclude="$(app_name)/js/.*" \ -czf $(appstore_package_name).tar.gz ../$(app_name) +# Installs composer dependencies including require-dev (phpunit, phpstan, +# nextcloud/ocp stubs). Separate from the `composer` target above, which +# passes --no-dev for production/appstore builds. +.PHONY: composer-dev +composer-dev: + composer install --prefer-dist + +# Runs the unit test suite, which only needs the nextcloud/ocp stub package +# (no live Nextcloud instance required) — this is what CI runs. .PHONY: test -test: composer +test: composer-dev $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.xml + +# Runs the integration test suite. Requires this app to be checked out inside +# a real Nextcloud server's apps/ directory with a working install — not run +# by CI yet (see the linked GitHub issue for the multi-database CI follow-up). +.PHONY: test-integration +test-integration: composer-dev $(CURDIR)/vendor/phpunit/phpunit/phpunit -c phpunit.integration.xml diff --git a/composer.json b/composer.json index b142981..3507361 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,28 @@ ], "require": {}, "require-dev": { - "christophwurst/nextcloud": "^24.0" + "nextcloud/ocp": "^34.0", + "phpunit/phpunit": "^10.5", + "phpstan/phpstan": "^1.11" + }, + "autoload": { + "psr-4": { + "OCA\\TimeTracker\\": "lib/" + } + }, + "autoload-dev": { + "psr-4": { + "OCA\\TimeTracker\\Tests\\": "tests/", + "OCP\\": "vendor/nextcloud/ocp/OCP/", + "NCU\\": "vendor/nextcloud/ocp/NCU/" + } + }, + "scripts": { + "lint": "find . -name '*.php' -not -path './vendor/*' -not -path './build/*' -not -path './js/*' -print0 | xargs -0 -n1 php -l", + "phpstan": "phpstan analyse --no-progress", + "test:unit": "phpunit -c phpunit.xml" + }, + "config": { + "sort-packages": true } } diff --git a/composer.lock b/composer.lock index cffd205..a012416 100644 --- a/composer.lock +++ b/composer.lock @@ -4,33 +4,95 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "296f87db0439fa6556d383ab1bd9038b", + "content-hash": "7389578d322e21100c665e143e0cbe68", "packages": [], "packages-dev": [ { - "name": "christophwurst/nextcloud", - "version": "v24.0.1", + "name": "myclabs/deep-copy", + "version": "1.13.4", "source": { "type": "git", - "url": "https://github.com/ChristophWurst/nextcloud_composer.git", - "reference": "f032acdff1502a7323f95a6524d163290f43b446" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ChristophWurst/nextcloud_composer/zipball/f032acdff1502a7323f95a6524d163290f43b446", - "reference": "f032acdff1502a7323f95a6524d163290f43b446", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { - "php": "^7.4 || ~8.0 || ~8.1", - "psr/container": "^1.1.1", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" + }, + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" + }, + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" + }, + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2025-08-01T08:46:24+00:00" + }, + { + "name": "nextcloud/ocp", + "version": "v34.0.1", + "source": { + "type": "git", + "url": "https://github.com/nextcloud-deps/ocp.git", + "reference": "3f920a7f46bae0c55643579ce25b6644a09065ff" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nextcloud-deps/ocp/zipball/3f920a7f46bae0c55643579ce25b6644a09065ff", + "reference": "3f920a7f46bae0c55643579ce25b6644a09065ff", + "shasum": "" + }, + "require": { + "php": "~8.2 || ~8.3 || ~8.4 || ~8.5", + "psr/clock": "^1.0", + "psr/container": "^2.0.2", "psr/event-dispatcher": "^1.0", - "psr/log": "^1.1" + "psr/http-client": "^1.0.3", + "psr/log": "^3.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "24.0.0-dev" + "dev-stable34": "34.0.0-dev" } }, "notification-url": "https://packagist.org/downloads/", @@ -41,171 +103,1994 @@ { "name": "Christoph Wurst", "email": "christoph@winzerhof-wurst.at" + }, + { + "name": "Joas Schilling", + "email": "coding@schilljs.com" } ], - "description": "Composer package containing Nextcloud's public API (classes, interfaces)", + "description": "Composer package containing Nextcloud's public OCP API and the unstable NCU API", "support": { - "issues": "https://github.com/ChristophWurst/nextcloud_composer/issues", - "source": "https://github.com/ChristophWurst/nextcloud_composer/tree/v24.0.1" + "issues": "https://github.com/nextcloud-deps/ocp/issues", + "source": "https://github.com/nextcloud-deps/ocp/tree/v34.0.1" }, - "abandoned": "nextcloud/ocp", - "time": "2022-06-02T14:16:47+00:00" + "time": "2026-06-18T02:35:58+00:00" }, { - "name": "psr/container", - "version": "1.1.2", + "name": "nikic/php-parser", + "version": "v5.7.0", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { - "php": ">=7.4.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Nikita Popov" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", + "description": "A PHP parser written in PHP", "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" + "parser", + "php" ], "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "php": ">=7.2.0" + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } + ], + "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.12.33", + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/37982d6fc7cbb746dda7773530cda557cdf119e1", + "reference": "37982d6fc7cbb746dda7773530cda557cdf119e1", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2026-02-28T20:30:03+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "10.1.16", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^10.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Standard interfaces for event handling.", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ - "events", - "psr", - "psr-14" + "coverage", + "testing", + "xunit" ], "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, - "time": "2019-01-08T18:20:26+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:31:57+00:00" }, { - "name": "psr/log", - "version": "1.1.4", + "name": "phpunit/php-file-iterator", + "version": "4.1.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T06:24:48+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:56:09+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "log", - "psr", - "psr-3" + "template" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-08-31T14:07:24+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" }, - "time": "2021-05-03T11:20:27+00:00" + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:57:52+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "10.5.63", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "33198268dad71e926626b618f3ec3966661e4d90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/33198268dad71e926626b618f3ec3966661e4d90", + "reference": "33198268dad71e926626b618f3ec3966661e4d90", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.5", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.4", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.1", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.5-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.63" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2026-01-27T05:48:37+00:00" + }, + { + "name": "psr/clock", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/clock.git", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/clock/zipball/e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "reference": "e41a24703d4560fd0acb709162f73b8adfc3aa0d", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Clock\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for reading the clock.", + "homepage": "https://github.com/php-fig/clock", + "keywords": [ + "clock", + "now", + "psr", + "psr-20", + "time" + ], + "support": { + "issues": "https://github.com/php-fig/clock/issues", + "source": "https://github.com/php-fig/clock/tree/1.0.0" + }, + "time": "2022-11-25T14:36:26+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+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" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:59:15+00:00" + }, + { + "name": "sebastian/comparator", + "version": "5.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "reference": "55dfef806eb7dfeb6e7a6935601fef866f8ca48d", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:25:16+00:00" + }, + { + "name": "sebastian/complexity", + "version": "3.2.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "68ff824baeae169ec9f2137158ee529584553799" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:37:17+00:00" + }, + { + "name": "sebastian/diff", + "version": "5.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:15:17+00:00" + }, + { + "name": "sebastian/environment", + "version": "6.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:47:14+00:00" + }, + { + "name": "sebastian/exporter", + "version": "5.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "0735b90f4da94969541dac1da743446e276defa6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/0735b90f4da94969541dac1da743446e276defa6", + "reference": "0735b90f4da94969541dac1da743446e276defa6", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2025-09-24T06:09:11+00:00" + }, + { + "name": "sebastian/global-state", + "version": "6.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:19:19+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-21T08:38:20+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:08:32+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:06:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/47e34210757a2f37a97dcd207d032e1b01e64c7a", + "reference": "47e34210757a2f37a97dcd207d032e1b01e64c7a", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2025-08-10T07:50:56+00:00" + }, + { + "name": "sebastian/type", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T07:10:45+00:00" + }, + { + "name": "sebastian/version", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-07T11:34:05+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, - "platform": [], - "platform-dev": [], - "plugin-api-version": "2.3.0" + "platform": {}, + "platform-dev": {}, + "plugin-api-version": "2.9.0" } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..69929e2 --- /dev/null +++ b/phpstan-baseline.neon @@ -0,0 +1,426 @@ +parameters: + ignoreErrors: + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$content\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$cost\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$email\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$end\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$from\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$group1\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$group2\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$hours\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$interval\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$name\\.$#" + count: 4 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$projectId\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$q\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$status\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$subject\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$timegroup\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$to\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to an undefined property OCP\\\\IRequest\\:\\:\\$workItem\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Access to static property \\$server on an unknown class OC\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Client\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Client\\:\\:setName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setHours\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setInterval\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setProjectId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Goal\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setClientId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setColor\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setCreatedByUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Project\\:\\:setName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Tag\\:\\:setCreatedAt\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Tag\\:\\:setName\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Tag\\:\\:setUserUid\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setFilterClients\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setFilterProjects\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setGroup1\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setGroup2\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setStatus\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setTimeGroup\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setTimeInterval\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setTotalDuration\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\Timeline\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setClientName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setCost\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setProjectName\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setTimeInterval\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setTimelineId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setTotalDuration\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\TimelineEntry\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setAdmin\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setClientId\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setCreatedAt\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToClient\\:\\:setUserUid\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setAccess\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setAdmin\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setCreatedAt\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setProjectId\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\UserToProject\\:\\:setUserUid\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setDetails\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setDuration\\(\\)\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setName\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setProjectId\\(\\)\\.$#" + count: 3 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setRunning\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setStart\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkInterval\\:\\:setUserUid\\(\\)\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkIntervalToTag\\:\\:setCreatedAt\\(\\)\\.$#" + count: 6 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkIntervalToTag\\:\\:setTagId\\(\\)\\.$#" + count: 6 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to an undefined method OCA\\\\TimeTracker\\\\Db\\\\WorkIntervalToTag\\:\\:setWorkIntervalId\\(\\)\\.$#" + count: 6 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to static method getUser\\(\\) on an unknown class OC_User\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Call to static method isAdminUser\\(\\) on an unknown class OC_User\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Undefined variable\\: \\$id$#" + count: 5 + path: lib/Controller/AjaxController.php + + - + message: "#^Variable \\$cost on left side of \\?\\? always exists and is not nullable\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Variable \\$intervals might not be defined\\.$#" + count: 1 + path: lib/Controller/AjaxController.php + + - + message: "#^Variable \\$repItems might not be defined\\.$#" + count: 2 + path: lib/Controller/AjaxController.php + + - + message: "#^Method OCA\\\\TimeTracker\\\\Db\\\\ProjectMapper\\:\\:delete\\(\\) should return OCP\\\\AppFramework\\\\Db\\\\Entity but empty return statement found\\.$#" + count: 2 + path: lib/Db/ProjectMapper.php + + - + message: "#^Access to an undefined property OCA\\\\TimeTracker\\\\Db\\\\TagMapper\\:\\:\\$dbengine\\.$#" + count: 4 + path: lib/Db/TagMapper.php + + - + message: "#^Call to an undefined method OCP\\\\DB\\\\QueryBuilder\\\\IQueryBuilder\\:\\:execute\\(\\)\\.$#" + count: 6 + path: lib/Migration/Version000000Date20210719124731.php + + - + message: "#^Call to method addColumn\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 69 + path: lib/Migration/Version000000Date20210719124731.php + + - + message: "#^Call to method setPrimaryKey\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 11 + path: lib/Migration/Version000000Date20210719124731.php + + - + message: "#^Call to method addColumn\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 17 + path: lib/Migration/Version000001Date20210719192031.php + + - + message: "#^Call to method hasColumn\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 2 + path: lib/Migration/Version000001Date20210719192031.php + + - + message: "#^Call to method setPrimaryKey\\(\\) on an unknown class Doctrine\\\\DBAL\\\\Schema\\\\Table\\.$#" + count: 2 + path: lib/Migration/Version000001Date20210719192031.php diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..49e0a9b --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,12 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: 3 + paths: + - lib + - appinfo + phpVersion: 80200 + bootstrapFiles: + - vendor/autoload.php + - tests/phpstan-bootstrap.php diff --git a/phpunit.integration.xml b/phpunit.integration.xml index eae19f1..bf0965b 100644 --- a/phpunit.integration.xml +++ b/phpunit.integration.xml @@ -1,4 +1,4 @@ - + ./tests/Integration diff --git a/tests/Integration/AppTest.php b/tests/Integration/AppTest.php index cabd9e5..708bafa 100644 --- a/tests/Integration/AppTest.php +++ b/tests/Integration/AppTest.php @@ -15,13 +15,13 @@ class AppTest extends TestCase { private $container; - public function setUp() { + public function setUp(): void { parent::setUp(); $app = new App('timetracker'); $this->container = $app->getContainer(); } - public function testAppInstalled() { + public function testAppInstalled(): void { $appManager = $this->container->query('OCP\App\IAppManager'); $this->assertTrue($appManager->isInstalled('timetracker')); } diff --git a/tests/Unit/Controller/PageControllerTest.php b/tests/Unit/Controller/PageControllerTest.php index 6df82e6..1c51594 100644 --- a/tests/Unit/Controller/PageControllerTest.php +++ b/tests/Unit/Controller/PageControllerTest.php @@ -2,30 +2,34 @@ namespace OCA\TimeTracker\Tests\Unit\Controller; -use PHPUnit_Framework_TestCase; - use OCP\AppFramework\Http\TemplateResponse; - +use OCP\IRequest; +use OCP\IUser; +use OCP\IUserSession; use OCA\TimeTracker\Controller\PageController; +use PHPUnit\Framework\TestCase; - -class PageControllerTest extends PHPUnit_Framework_TestCase { +class PageControllerTest extends TestCase { private $controller; private $userId = 'john'; - public function setUp() { - $request = $this->getMockBuilder('OCP\IRequest')->getMock(); + public function setUp(): void { + $request = $this->createMock(IRequest::class); + $user = $this->createMock(IUser::class); + $user->method('getUID')->willReturn($this->userId); + $userSession = $this->createMock(IUserSession::class); + $userSession->method('getUser')->willReturn($user); $this->controller = new PageController( - 'timetracker', $request, $this->userId + 'timetracker', $request, $userSession ); } - public function testIndex() { + public function testIndex(): void { $result = $this->controller->index(); $this->assertEquals('index', $result->getTemplateName()); - $this->assertTrue($result instanceof TemplateResponse); + $this->assertInstanceOf(TemplateResponse::class, $result); } } diff --git a/tests/bootstrap.integration.php b/tests/bootstrap.integration.php new file mode 100644 index 0000000..d09c421 --- /dev/null +++ b/tests/bootstrap.integration.php @@ -0,0 +1,15 @@ +addValidRoot(OC::$SERVERROOT . '/tests'); + +// Fix for "Autoload path not allowed: .../timetracker/tests/testcase.php" +\OC_App::loadApp('timetracker'); + +OC_Hook::clear(); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 20a5605..85cd034 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -4,16 +4,4 @@ define('PHPUNIT_RUN', 1); } -require_once __DIR__.'/../../../lib/base.php'; - -// Fix for "Autoload path not allowed: .../tests/lib/testcase.php" -\OC::$loader->addValidRoot(OC::$SERVERROOT . '/tests'); - -// Fix for "Autoload path not allowed: .../timetracker/tests/testcase.php" -\OC_App::loadApp('timetracker'); - -if(!class_exists('PHPUnit_Framework_TestCase')) { - require_once('PHPUnit/Autoload.php'); -} - -OC_Hook::clear(); +require_once __DIR__ . '/../vendor/autoload.php'; diff --git a/tests/phpstan-bootstrap.php b/tests/phpstan-bootstrap.php new file mode 100644 index 0000000..db7c7f3 --- /dev/null +++ b/tests/phpstan-bootstrap.php @@ -0,0 +1,12 @@ + Date: Fri, 3 Jul 2026 22:42:40 +0200 Subject: [PATCH 02/12] Replace Travis with GitHub Actions CI .travis.yml was pinned to PHP 5.6-7.1 and long dead. Adds three free GitHub Actions workflows (unlimited minutes on public repos), each a simplified adaptation of Nextcloud's reusable workflow templates (nextcloud/.github): - lint-php.yml: composer validate + php -l, matrix over PHP 8.2/8.3 - static-analysis.yml: PHPStan against the baseline added in the previous commit - phpunit.yml: the unit suite only (no live server/DB needed, so no external services to boot); the server-backed integration suite is intentionally deferred to the multi-database CI follow-up from the linked issue Closes mtierltd/timetracker#257 (steps 1 and 2 only; unit tests for mappers/report queries and multi-database CI remain as follow-up). Co-Authored-By: Claude Sonnet 5 --- .github/workflows/lint-php.yml | 49 ++++++++++++++++++++ .github/workflows/phpunit.yml | 45 +++++++++++++++++++ .github/workflows/static-analysis.yml | 41 +++++++++++++++++ .travis.yml | 64 --------------------------- 4 files changed, 135 insertions(+), 64 deletions(-) create mode 100644 .github/workflows/lint-php.yml create mode 100644 .github/workflows/phpunit.yml create mode 100644 .github/workflows/static-analysis.yml delete mode 100644 .travis.yml diff --git a/.github/workflows/lint-php.yml b/.github/workflows/lint-php.yml new file mode 100644 index 0000000..f8b2e8b --- /dev/null +++ b/.github/workflows/lint-php.yml @@ -0,0 +1,49 @@ +# Cheap, high-value check: php -l syntax linting + composer.json validation. +# Adapted from Nextcloud's reusable workflow templates (nextcloud/.github), +# simplified to a fixed PHP matrix instead of deriving one from appinfo/info.xml +# (this app's declared min-version="20" predates PHP 8, which isn't a +# realistic target — see the linked issue for the follow-up on tightening that). +name: Lint PHP + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: lint-php-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + php-lint: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: ['8.2', '8.3'] + + name: php-lint (PHP ${{ matrix.php-versions }}) + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + + - name: composer validate + run: composer validate + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: Lint (php -l) + run: composer run lint diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..c8ea17e --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,45 @@ +# Unit tests only, against the nextcloud/ocp stub package — no live +# Nextcloud server or database is booted, which keeps this job fast and free +# of external services. tests/Integration (real server + DB) is intentionally +# not run here; see the linked GitHub issue for the multi-database follow-up. +name: PHPUnit + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: phpunit-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + unit-tests: + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php-versions: ['8.2', '8.3'] + + name: unit-tests (PHP ${{ matrix.php-versions }}) + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Set up php ${{ matrix.php-versions }} + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: ${{ matrix.php-versions }} + coverage: none + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: PHPUnit + run: composer run test:unit diff --git a/.github/workflows/static-analysis.yml b/.github/workflows/static-analysis.yml new file mode 100644 index 0000000..3c9f0f6 --- /dev/null +++ b/.github/workflows/static-analysis.yml @@ -0,0 +1,41 @@ +# Static analysis with PHPStan. Existing findings are frozen in +# phpstan-baseline.neon (mostly missing Doctrine DBAL type stubs and a +# runtime class_alias() static analysis can't see through) so this starts +# green; only newly introduced issues fail the build. +name: Static analysis + +on: + pull_request: + push: + branches: [master] + +permissions: + contents: read + +concurrency: + group: phpstan-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + +jobs: + phpstan: + runs-on: ubuntu-latest + + name: static-phpstan-analysis + + steps: + - name: Checkout + uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 + with: + persist-credentials: false + + - name: Set up php + uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # 2.37.2 + with: + php-version: '8.3' + coverage: none + + - name: Install dependencies + run: composer install --prefer-dist --no-progress + + - name: PHPStan + run: composer run phpstan diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 8b535dd..0000000 --- a/.travis.yml +++ /dev/null @@ -1,64 +0,0 @@ -sudo: false -dist: trusty -language: php -php: - - 5.6 - - 7 - - 7.1 -env: - global: - - CORE_BRANCH=stable14 - matrix: - - DB=pgsql - -matrix: - allow_failures: - - env: DB=pgsql CORE_BRANCH=master - include: - - php: 5.6 - env: DB=sqlite - - php: 5.6 - env: DB=mysql - - php: 5.6 - env: DB=pgsql CORE_BRANCH=master - fast_finish: true - - -before_install: - # enable a display for running JavaScript tests - - export DISPLAY=:99.0 - - sh -e /etc/init.d/xvfb start - - nvm install 8 - - npm install -g npm@latest - - make - - make appstore - # install core - - cd ../ - - git clone https://github.com/nextcloud/server.git --recursive --depth 1 -b $CORE_BRANCH nextcloud - - mv "$TRAVIS_BUILD_DIR" nextcloud/apps/timetracker - -before_script: - - if [[ "$DB" == 'pgsql' ]]; then createuser -U travis -s oc_autotest; fi - - if [[ "$DB" == 'mysql' ]]; then mysql -u root -e 'create database oc_autotest;'; fi - - if [[ "$DB" == 'mysql' ]]; then mysql -u root -e "CREATE USER 'oc_autotest'@'localhost' IDENTIFIED BY '';"; fi - - if [[ "$DB" == 'mysql' ]]; then mysql -u root -e "grant all on oc_autotest.* to 'oc_autotest'@'localhost';"; fi - - cd nextcloud - - mkdir data - - ./occ maintenance:install --database-name oc_autotest --database-user oc_autotest --admin-user admin --admin-pass admin --database $DB --database-pass='' - - ./occ app:enable timetracker - - php -S localhost:8080 & - - cd apps/timetracker - -script: - - make test - -after_failure: - - cat ../../data/nextcloud.log - -addons: - firefox: 'latest' - mariadb: '10.1' - -services: - - postgresql - - mariadb From ea071f193e00847204e1c19510ccba2a8b469f80 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Sun, 12 Jul 2026 19:17:43 +0200 Subject: [PATCH 03/12] Remove FontAwesome and dead KingTable code Deletes unused js/src/kingtable.js and css/kingtable.css (~203 KB), plus the FontAwesome stylesheet and webfonts/ directory (~2.7 MB), replacing the 4 FontAwesome icon classes still in use with their native Nextcloud equivalents across 9 usage sites in templates and JS formatters. Co-Authored-By: Claude Sonnet 5 --- css/all.css | 4223 ------------------------------- css/kingtable.css | 2624 ------------------- js/src/clients.js | 2 +- js/src/goals.js | 2 +- js/src/kingtable.js | 15 - js/src/tags.js | 2 +- js/src/timelines-admin.js | 2 +- js/src/timer.js | 2 +- templates/content/dashboard.php | 4 +- templates/content/index.php | 4 +- templates/content/reports.php | 4 +- templates/content/timelines.php | 4 +- templates/index.php | 1 - webfonts/fa-brands-400.eot | Bin 134000 -> 0 bytes webfonts/fa-brands-400.svg | 1 - webfonts/fa-brands-400.ttf | Bin 133764 -> 0 bytes webfonts/fa-brands-400.woff | Bin 86736 -> 0 bytes webfonts/fa-brands-400.woff2 | Bin 73936 -> 0 bytes webfonts/fa-regular-400.eot | Bin 40308 -> 0 bytes webfonts/fa-regular-400.svg | 1 - webfonts/fa-regular-400.ttf | Bin 40080 -> 0 bytes webfonts/fa-regular-400.woff | Bin 18164 -> 0 bytes webfonts/fa-regular-400.woff2 | Bin 14868 -> 0 bytes webfonts/fa-solid-900.eot | Bin 208828 -> 0 bytes webfonts/fa-solid-900.svg | 1 - webfonts/fa-solid-900.ttf | Bin 208608 -> 0 bytes webfonts/fa-solid-900.woff | Bin 102120 -> 0 bytes webfonts/fa-solid-900.woff2 | Bin 79072 -> 0 bytes 28 files changed, 13 insertions(+), 6879 deletions(-) delete mode 100644 css/all.css delete mode 100644 css/kingtable.css delete mode 100644 js/src/kingtable.js delete mode 100644 webfonts/fa-brands-400.eot delete mode 100644 webfonts/fa-brands-400.svg delete mode 100644 webfonts/fa-brands-400.ttf delete mode 100644 webfonts/fa-brands-400.woff delete mode 100644 webfonts/fa-brands-400.woff2 delete mode 100644 webfonts/fa-regular-400.eot delete mode 100644 webfonts/fa-regular-400.svg delete mode 100644 webfonts/fa-regular-400.ttf delete mode 100644 webfonts/fa-regular-400.woff delete mode 100644 webfonts/fa-regular-400.woff2 delete mode 100644 webfonts/fa-solid-900.eot delete mode 100644 webfonts/fa-solid-900.svg delete mode 100644 webfonts/fa-solid-900.ttf delete mode 100644 webfonts/fa-solid-900.woff delete mode 100644 webfonts/fa-solid-900.woff2 diff --git a/css/all.css b/css/all.css deleted file mode 100644 index 3f65700..0000000 --- a/css/all.css +++ /dev/null @@ -1,4223 +0,0 @@ -/*! - * Font Awesome Free 5.6.1 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, -.fas, -.far, -.fal, -.fab { - -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: 0.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: solid 0.08em #eee; - border-radius: .1em; - padding: .2em .25em .15em; } - -.fa-pull-left { - float: left; } - -.fa-pull-right { - float: right; } - -.fa.fa-pull-left, -.fas.fa-pull-left, -.far.fa-pull-left, -.fal.fa-pull-left, -.fab.fa-pull-left { - margin-right: .3em; } - -.fa.fa-pull-right, -.fas.fa-pull-right, -.far.fa-pull-right, -.fal.fa-pull-right, -.fab.fa-pull-right { - margin-left: .3em; } - -.fa-spin { - -webkit-animation: fa-spin 2s infinite linear; - animation: fa-spin 2s infinite linear; } - -.fa-pulse { - -webkit-animation: fa-spin 1s infinite steps(8); - animation: fa-spin 1s infinite steps(8); } - -@-webkit-keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); } } - -@keyframes fa-spin { - 0% { - -webkit-transform: rotate(0deg); - transform: rotate(0deg); } - 100% { - -webkit-transform: rotate(360deg); - transform: rotate(360deg); } } - -.fa-rotate-90 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=1)"; - -webkit-transform: rotate(90deg); - transform: rotate(90deg); } - -.fa-rotate-180 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2)"; - -webkit-transform: rotate(180deg); - transform: rotate(180deg); } - -.fa-rotate-270 { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=3)"; - -webkit-transform: rotate(270deg); - transform: rotate(270deg); } - -.fa-flip-horizontal { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=0, mirror=1)"; - -webkit-transform: scale(-1, 1); - transform: scale(-1, 1); } - -.fa-flip-vertical { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; - -webkit-transform: scale(1, -1); - transform: scale(1, -1); } - -.fa-flip-horizontal.fa-flip-vertical { - -ms-filter: "progid:DXImageTransform.Microsoft.BasicImage(rotation=2, mirror=1)"; - -webkit-transform: scale(-1, -1); - transform: scale(-1, -1); } - -:root .fa-rotate-90, -:root .fa-rotate-180, -:root .fa-rotate-270, -:root .fa-flip-horizontal, -:root .fa-flip-vertical { - -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; } - -/* Font Awesome uses the Unicode Private Use Area (PUA) to ensure screen -readers do not read off random characters that represent icons */ -.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-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-balance-scale:before { - content: "\f24e"; } - -.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-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-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-open:before { - content: "\f518"; } - -.fa-book-reader:before { - content: "\f5da"; } - -.fa-bookmark:before { - content: "\f02e"; } - -.fa-bowling-ball:before { - content: "\f436"; } - -.fa-box:before { - content: "\f466"; } - -.fa-box-open:before { - content: "\f49e"; } - -.fa-boxes:before { - content: "\f468"; } - -.fa-braille:before { - content: "\f2a1"; } - -.fa-brain:before { - content: "\f5dc"; } - -.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-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-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-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-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-church:before { - content: "\f51d"; } - -.fa-circle:before { - content: "\f111"; } - -.fa-circle-notch:before { - content: "\f1ce"; } - -.fa-city:before { - content: "\f64f"; } - -.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-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-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-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-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-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-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-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-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-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-fantasy-flight-games:before { - content: "\f6dc"; } - -.fa-fast-backward:before { - content: "\f049"; } - -.fa-fast-forward:before { - content: "\f050"; } - -.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-extinguisher:before { - content: "\f134"; } - -.fa-firefox:before { - content: "\f269"; } - -.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-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-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-usd:before { - content: "\f4c0"; } - -.fa-hand-lizard:before { - content: "\f258"; } - -.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-spock:before { - content: "\f259"; } - -.fa-hands:before { - content: "\f4c2"; } - -.fa-hands-helping:before { - content: "\f4c4"; } - -.fa-handshake:before { - content: "\f2b5"; } - -.fa-hanukiah:before { - content: "\f6e6"; } - -.fa-hashtag:before { - content: "\f292"; } - -.fa-hat-wizard:before { - content: "\f6e8"; } - -.fa-haykal:before { - content: "\f666"; } - -.fa-hdd:before { - content: "\f0a0"; } - -.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-hot-tub:before { - content: "\f593"; } - -.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-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-icicles:before { - content: "\f7ad"; } - -.fa-id-badge:before { - content: "\f2c1"; } - -.fa-id-card:before { - content: "\f2c2"; } - -.fa-id-card-alt:before { - content: "\f47f"; } - -.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-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-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-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-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-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-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-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-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-nintendo-switch:before { - content: "\f418"; } - -.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-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-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-carry:before { - content: "\f4ce"; } - -.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-slash:before { - content: "\f3dd"; } - -.fa-phone-square:before { - content: "\f098"; } - -.fa-phone-volume:before { - content: "\f2a0"; } - -.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-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-place-of-worship:before { - content: "\f67f"; } - -.fa-plane:before { - content: "\f072"; } - -.fa-plane-arrival:before { - content: "\f5af"; } - -.fa-plane-departure:before { - content: "\f5b0"; } - -.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-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-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-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-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-ship:before { - content: "\f21a"; } - -.fa-shipping-fast:before { - content: "\f48b"; } - -.fa-shirtsinbulk:before { - content: "\f214"; } - -.fa-shoe-prints:before { - content: "\f54b"; } - -.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-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-up:before { - content: "\f15e"; } - -.fa-sort-amount-down:before { - content: "\f160"; } - -.fa-sort-amount-up:before { - content: "\f161"; } - -.fa-sort-down:before { - content: "\f0dd"; } - -.fa-sort-numeric-down:before { - content: "\f162"; } - -.fa-sort-numeric-up:before { - content: "\f163"; } - -.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-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-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-store:before { - content: "\f54e"; } - -.fa-store-alt:before { - content: "\f54f"; } - -.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-swimmer:before { - content: "\f5c4"; } - -.fa-swimming-pool:before { - content: "\f5c5"; } - -.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-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-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-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-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-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-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-vk:before { - content: "\f189"; } - -.fa-vnv:before { - content: "\f40b"; } - -.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-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-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 { - border: 0; - clip: rect(0, 0, 0, 0); - height: 1px; - margin: -1px; - overflow: hidden; - padding: 0; - position: absolute; - width: 1px; } - -.sr-only-focusable:active, .sr-only-focusable:focus { - clip: auto; - height: auto; - margin: 0; - overflow: visible; - position: static; - width: auto; } -@font-face { - font-family: 'Font Awesome 5 Brands'; - font-style: normal; - font-weight: normal; - src: url("../webfonts/fa-brands-400.eot"); - src: url("../webfonts/fa-brands-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-brands-400.woff2") format("woff2"), url("../webfonts/fa-brands-400.woff") format("woff"), url("../webfonts/fa-brands-400.ttf") format("truetype"), url("../webfonts/fa-brands-400.svg#fontawesome") format("svg"); } - -.fab { - font-family: 'Font Awesome 5 Brands'; } -@font-face { - font-family: 'Font Awesome 5 Free'; - font-style: normal; - font-weight: 400; - src: url("../webfonts/fa-regular-400.eot"); - src: url("../webfonts/fa-regular-400.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-regular-400.woff2") format("woff2"), url("../webfonts/fa-regular-400.woff") format("woff"), url("../webfonts/fa-regular-400.ttf") format("truetype"), url("../webfonts/fa-regular-400.svg#fontawesome") format("svg"); } - -.far { - font-family: 'Font Awesome 5 Free'; - font-weight: 400; } -@font-face { - font-family: 'Font Awesome 5 Free'; - font-style: normal; - font-weight: 900; - src: url("../webfonts/fa-solid-900.eot"); - src: url("../webfonts/fa-solid-900.eot?#iefix") format("embedded-opentype"), url("../webfonts/fa-solid-900.woff2") format("woff2"), url("../webfonts/fa-solid-900.woff") format("woff"), url("../webfonts/fa-solid-900.ttf") format("truetype"), url("../webfonts/fa-solid-900.svg#fontawesome") format("svg"); } - -.fa, -.fas { - font-family: 'Font Awesome 5 Free'; - font-weight: 900; } diff --git a/css/kingtable.css b/css/kingtable.css deleted file mode 100644 index 59ba07e..0000000 --- a/css/kingtable.css +++ /dev/null @@ -1,2624 +0,0 @@ -/*! - * KingTable 2.0.0 - * https://github.com/RobertoPrevato/KingTable - * - * Copyright 2018, Roberto Prevato - * https://robertoprevato.github.io - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ - -.theme-bronze .king-table, .theme-clear .king-table, .theme-dark .king-table, .theme-midnight .king-table, .theme-olive .king-table, .theme-ultramarine .king-table { - border-collapse: collapse; - margin-bottom: 10px -} - -.king-table-region .pagination-bar { - position: relative; - font-size: 12px; - line-height: 17px; - white-space: nowrap; - padding: 4px 10px 0; - height: 26px -} - -.king-table-region .pagination-bar.o-icons { - padding: 0 -} - -.king-table-region .pagination-bar.o-icons .pagination-bar-buttons { - box-sizing: border-box; - background-color: #f0f8ff; - height: 26px; - display: inline-block; - padding-top: 3px -} - -.king-table-region .pagination-bar .search-field { - font-size: 11px; - line-height: 12px; - height: 16px; - position: relative; - bottom: 4px; - background-repeat: no-repeat; - background-position: 147px 3px; - padding-right: 20px!important; - width: 140px; - z-index: 9999 -} - -.king-table-region .pagination-bar .btn-filters-wizard { - top: 5px; - position: absolute; - height: 22px; - font-size: 11px; - padding: 0 10px; - margin-left: 8px -} - -.king-table-region .pagination-bar .total-page-count { - display: inline-block; - min-width: 30px -} - -.king-table-region .pagination-bar .pagination-bar-filters .btn-advanced-filters { - margin-left: 10px; - margin-top: 0; - vertical-align: top; - position: relative; - top: 1px; - margin-bottom: 10px -} - -.king-table-region .pagination-bar input, .king-table-region .pagination-bar select, .king-table-region .pagination-bar span { - font-size: 11px; - margin-right: 0; - line-height: normal -} - -.king-table-region .pagination-bar .pagination-button, .king-table-region .pagination-bar .pagination-button-disabled { - display: inline-block; - width: 22px; - height: 22px -} - -.king-table-region .pagination-bar .pagination-button-disabled.oi, .king-table-region .pagination-bar .pagination-button.oi { - background-image: none; - position: relative; - top: 0; - left: 0 -} - -.king-table-region .pagination-bar .pagination-button-disabled.oi:before, .king-table-region .pagination-bar .pagination-button.oi:before { - margin: 5px; - top: 0; - position: absolute; - left: 1px -} - -.king-table-region .pagination-bar .pagination-button-disabled.oi { - opacity: .2 -} - -.king-table-region .pagination-bar .pagination-button { - cursor: pointer -} - -.king-table-region .pagination-bar .separator { - display: inline-block; - width: 6px; - border-right: 1px solid #666; - height: 13px; - cursor: default; - margin: 0 4px 5px -} - -.king-table-region .pagination-bar-refresh { - background-position: -22px 0 -} - -.king-table-region .pagination-bar-next-item, .king-table-region .pagination-bar-next-page { - background-position: -40px -22px -} - -.king-table-region .pagination-bar-last-item, .king-table-region .pagination-bar-last-page { - background-position: -66px -22px -} - -.king-table-region .pagination-bar-prev-item, .king-table-region .pagination-bar-prev-page { - background-position: -22px -22px -} - -.king-table-region .pagination-bar-first-item, .king-table-region .pagination-bar-first-page { - background-position: 0 -22px -} - -.king-table-region .pagination-bar-first-item-disabled, .king-table-region .pagination-bar-first-page-disabled { - background-position: 0 -44px -} - -.king-table-region .pagination-bar-prev-item-disabled, .king-table-region .pagination-bar-prev-page-disabled { - background-position: -23px -43px -} - -.king-table-region .pagination-bar-last-item-disabled, .king-table-region .pagination-bar-last-page-disabled { - background-position: -66px -44px -} - -.king-table-region .pagination-bar-next-item-disabled, .king-table-region .pagination-bar-next-page-disabled { - background-position: -40px -44px -} - -.king-table-region .pagination-bar .valigned { - position: relative; - bottom: 9px -} - -.king-table-region .pagination-bar select.valigned { - bottom: 6px; - margin-left: 3px; - margin-top: 2px; - padding: 0; - width: 60px -} - -.king-table-region .pagination-bar-item-number, .king-table-region .pagination-bar-page-number { - position: relative; - bottom: 10px; - margin-top: 2px; - padding: 0; - width: 30px -} - -.king-table-region .pagination-bar-item-number-disabled, .king-table-region .pagination-bar-page-number-disabled { - position: relative; - bottom: 10px; - margin-top: 2px; - padding: 0 0 0 2px; - width: 32px; - display: inline-block; - text-align: right -} - -.king-table-region .pagination-bar img { - padding: 2px -} - -.king-table-region .pagination-bar span img { - border: none; - border: 1px solid transparent -} - -.king-table-region .pagination-bar fieldset span { - font-style: normal -} - -.king-table-region .color-chart { - text-align: center -} - -.king-table-region .color-scheme-cell { - height: 20px; - width: 90px; - margin: 5px; - border: 1px solid #222; - display: inline-block -} - -.king-table-region input[type=text].pagination-bar-page-number { - text-shadow: 0 0 #000; - font-size: 11px; - line-height: 12px; - position: relative; - bottom: 9px; - background-repeat: no-repeat; - background-position: 147px 3px; - padding-right: 20px!important; - z-index: 9999; - border-radius: 0; - height: 14px; - margin: 4px; - color: #555 -} - -.king-table-region .filters-region { - font-size: 12px; - padding-top: 2px; - border-bottom: 1px solid #ccc; - display: none -} - -.king-table-region .filters-region .buttons { - padding: 0 10px 15px 15px -} - -.king-table-region .ug-submenu, .king-table-region .ug-submenu label, .king-table-region .ug-submenu>a, .king-table-region .ug-submenu>span[tabindex] { - position: relative -} - -.king-table-region .ug-submenu label .oi, .king-table-region .ug-submenu>a .oi, .king-table-region .ug-submenu>span[tabindex] .oi { - position: absolute; - right: 6px; - top: 5px; - font-size: 9px -} - -.king-table-region .ug-submenu>.ug-menu { - top: -35%; - left: 100% -} - -.king-table-region .ug-menu { - position: absolute; - top: 100%; - left: 0; - z-index: 1000; - display: none; - float: left; - min-width: 160px; - padding: 5px 0; - margin: 2px 0 0; - font-size: 14px; - text-align: left; - list-style: none; - background-color: #fff; - -webkit-background-clip: padding-box; - background-clip: padding-box; - border: 1px solid #ccc; - border: 1px solid rgba(0, 0, 0, .15); - border-radius: 4px; - -webkit-box-shadow: 0 6px 12px rgba(0, 0, 0, .175); - box-shadow: 0 6px 12px rgba(0, 0, 0, .175) -} - -.king-table-container, .king-table-region .ug-menu li { - position: relative -} - -.king-table-region .ug-menu .open>a, .king-table-region .ug-menu .open>label, .king-table-region .ug-menu .open>span[tabindex] { - background-color: #eee -} - -.king-table-region .ug-menu input[type=checkbox], .king-table-region .ug-menu input[type=radio] { - position: absolute; - left: 3px; - margin: 6px; - z-index: 10 -} - -.king-table-region .ug-menu-right, .king-table-region .ug-menu.pull-right { - right: 0; - left: auto -} - -.king-table-region .ug-menu .divider { - height: 1px; - margin: 9px 0; - overflow: hidden; - background-color: #e5e5e5 -} - -.king-table-region .ug-menu>li label, .king-table-region .ug-menu>li>a, .king-table-region .ug-menu>li>span[tabindex] { - display: block; - padding: 3px 20px; - clear: both; - font-weight: 400; - line-height: 1.42857143; - color: #333; - white-space: nowrap; - font-size: 12px -} - -.king-table-region .ug-menu>li label { - padding-left: 30px -} - -.king-table-region .ug-menu>li>a:focus, .king-table-region .ug-menu>li>a:hover, .king-table-region .ug-menu>li>label:hover, .king-table-region .ug-menu>li>span[tabindex]:focus, .king-table-region .ug-menu>li>span[tabindex]:hover { - color: #262626; - text-decoration: none; - background-color: #f5f5f5 -} - -.king-table-region .ug-menu>.active>a, .king-table-region .ug-menu>.active>a:focus, .king-table-region .ug-menu>.active>a:hover, .king-table-region .ug-menu>.active>label, .king-table-region .ug-menu>.active>span[tabindex], .king-table-region .ug-menu>.active>span[tabindex]:focus, .king-table-region .ug-menu>.active>span[tabindex]:hover { - color: #fff; - text-decoration: none; - background-color: #337ab7; - outline: 0 -} - -.king-table-region .ug-menu>.disabled>a, .king-table-region .ug-menu>.disabled>a:focus, .king-table-region .ug-menu>.disabled>a:hover, .king-table-region .ug-menu>.disabled>label, .king-table-region .ug-menu>.disabled>span[tabindex], .king-table-region .ug-menu>.disabled>span[tabindex]:focus, .king-table-region .ug-menu>.disabled>span[tabindex]:hover { - color: #777 -} - -.king-table-region .ug-menu>.disabled>a:focus, .king-table-region .ug-menu>.disabled>a:hover, .king-table-region .ug-menu>.disabled>label, .king-table-region .ug-menu>.disabled>span[tabindex]:focus, .king-table-region .ug-menu>.disabled>span[tabindex]:hover { - text-decoration: none; - cursor: not-allowed; - background-color: transparent; - background-image: none; - filter: progid:DXImageTransform.Microsoft.gradient(enabled=false) -} - -.theme-flatblack .search-field, .theme-flatwhite .search-field { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==) -} - -.king-table-region .open>.ug-menu { - display: block -} - -.king-table-region .open>a, .king-table-region .open>span[tabindex] { - outline: 0 -} - -.king-table-region .ug-menu-left { - right: auto; - left: 0 -} - -.king-table-region .dropdown-header { - display: block; - padding: 3px 20px; - font-size: 12px; - line-height: 1.42857143; - color: #777; - white-space: nowrap -} - -.king-table-region .dropdown-backdrop { - position: fixed; - top: 0; - right: 0; - bottom: 0; - left: 0; - z-index: 990 -} - -.king-table-region .pull-right>.ug-menu { - right: 0; - left: auto -} - -.king-table-region .dropup .caret, .king-table-region .navbar-fixed-bottom .dropdown .caret { - content: ""; - border-top: 0; - border-bottom: 4px dashed; - border-bottom: 4px solid\9 -} - -.king-table-region .dropup .ug-menu, .king-table-region .navbar-fixed-bottom .dropdown .ug-menu { - top: auto; - bottom: 100%; - margin-bottom: 2px -} - -.king-table-region .tools-region { - float: left; - margin-right: 5px -} - -.king-table-region .tools-region .ug-expander { - display: inline-block; - cursor: pointer; - padding: 5px 7px -} - -.king-table-region .tools-region:hover .menu { - display: block -} - -.theme-flatwhite .king-table tr { - border-bottom: 1px solid #eee -} - -.theme-flatwhite .pagination-bar .oi { - color: #666 -} - -.theme-flatwhite .king-table-head { - background-color: #FFF -} - -.theme-flatwhite .king-table a { - color: #000 -} - -.theme-flatwhite .king-table-body tr:hover { - background-color: #F7F7F7 -} - -.theme-flatwhite .pagination-bar { - background-color: #FFF; - border: 0; - border-bottom: 1px solid #ccc -} - -.theme-flatwhite .pagination-bar .pagination-button, .theme-flatwhite .pagination-bar .pagination-button-disabled, .theme-flatwhite .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-flatwhite .pagination-bar .separator { - border-right: 1px solid #D6D6D6 -} - -.theme-flatwhite .pagination-bar .search-field, .theme-flatwhite .pagination-bar select { - border-radius: 0 -} - -.theme-flatwhite .kt-search-highlight { - background-color: #ff0 -} - -.theme-flatwhite { - color: #000; - background-color: #FFF -} - -.theme-flatwhite hr { - border-top: 1px solid #aaa; - border-bottom: 1px solid #fff -} - -.theme-flatblack .king-table tr { - border-bottom: 1px solid #4A1111 -} - -.theme-flatblack .king-table-head { - background-color: #000 -} - -.theme-flatblack .filters-region { - border-bottom-color: #000 -} - -.theme-flatblack a { - color: #DADAD4 -} - -.theme-flatblack .king-table-body tr:hover { - background-color: #2D0303 -} - -.theme-flatblack .pagination-bar { - background-color: #000; - border: 1px solid rgba(18, 18, 18, .87); - border-top: 0 -} - -.theme-flatblack .pagination-bar .pagination-button, .theme-flatblack .pagination-bar .pagination-button-disabled, .theme-flatblack .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-clear .king-table-container, .theme-flatblack hr { - border-top: 1px solid #aaa -} - -.theme-flatblack .pagination-bar .separator { - border-right: 1px solid #666 -} - -.theme-flatblack .pagination-bar .search-field, .theme-flatblack .pagination-bar select { - border-radius: 0 -} - -.theme-flatblack .kt-search-highlight { - background-color: #791919 -} - -.theme-flatblack .king-table-container .preloader-mask { - opacity: .5; - background-color: #5F0909 -} - -.theme-flatblack .king-table-region .ug-menu { - box-shadow: 0 6px 12px #691010; - background: #111; - color: #DADAD4 -} - -.theme-flatblack .king-table-region .ug-menu li { - border-bottom: 1px solid #4A1111 -} - -.theme-flatblack .king-table-region .ug-menu li a, .theme-flatblack .king-table-region .ug-menu li label, .theme-flatblack .king-table-region .ug-menu li span { - color: #DADAD4 -} - -.theme-flatblack .king-table-region .ug-menu li a:focus, .theme-flatblack .king-table-region .ug-menu li a:hover, .theme-flatblack .king-table-region .ug-menu li label:focus, .theme-flatblack .king-table-region .ug-menu li label:hover, .theme-flatblack .king-table-region .ug-menu li span:focus, .theme-flatblack .king-table-region .ug-menu li span:hover { - color: #DADAD4; - background-color: #2D0303 -} - -.theme-flatblack .king-table-region .ug-menu li.open>a, .theme-flatblack .king-table-region .ug-menu li.open>label, .theme-flatblack .king-table-region .ug-menu li.open>span { - background-color: #2D0303 -} - -.theme-flatblack { - color: #DADAD4; - background-color: #000 -} - -.theme-flatblack .camo-btn { - color: #DADAD4 -} - -.theme-flatblack hr { - border-bottom: 1px solid #fff -} - -.theme-clear .king-table-head { - background-color: #eee -} - -.theme-clear .filters-region { - background-color: #e6e6e6 -} - -.theme-clear .king-table { - background: #eee; - border: none; - font-family: Sans-Serif; - font-size: 12px; - line-height: 17px; - border-bottom: 1px solid #bbb -} - -.theme-clear .king-table-gallery { - background-color: #EEE -} - -.theme-clear .king-table-gallery li>span { - border-bottom: 1px solid #777 -} - -.theme-clear .king-table caption { - border: 1px solid #d0d0d0; - font-weight: 700; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAFxABAQEBAAAAAAAAAAAAAAAAABMBYf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVlMEdegIKgA//2Q==) top left #fff -} - -.theme-clear .king-table tr td.row-number { - width: 40px; - text-align: center -} - -.theme-clear .king-table a { - color: #000 -} - -.theme-clear .king-table a:hover { - color: #C00 -} - -.theme-clear .king-table .king-table tr, .theme-clear .king-table .king-table-head tr { - width: 100%; - border-color: #ccc -} - -.theme-clear .king-table-body tr:hover:nth-child(even), .theme-clear .king-table-body tr:hover:nth-child(odd) { - background-color: #fefefe -} - -.theme-clear .king-table-body tr:hover:nth-child(even).king-table-empty, .theme-clear .king-table-body tr:hover:nth-child(even).king-table-error, .theme-clear .king-table-body tr:hover:nth-child(odd).king-table-empty, .theme-clear .king-table-body tr:hover:nth-child(odd).king-table-error { - background: #eee -} - -.theme-clear .king-table .king-table-head tr { - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAFxABAQEBAAAAAAAAAAAAAAAAABMBYf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVlMEdegIKgA//2Q==) top left repeat-x #d7d7d7; - height: 18px -} - -.theme-clear .king-table tr th { - text-align: left; - border: 1px solid #d0d0d0; - border-top: 1px solid #fff -} - -.theme-clear .king-table tr td { - line-height: 15px; - border-right: 1px solid #ddd; - border-bottom: 1px solid #ddd -} - -.theme-clear .king-table tr td.row-number, .theme-clear .king-table tr th.row-number { - border: 1px solid #d0d0d0; - border-top: 1px solid #fff; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAFxABAQEBAAAAAAAAAAAAAAAAABMBYf/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDVlMEdegIKgA//2Q==) top left repeat-x #d7d7d7 -} - -.theme-clear .pagination-bar { - background-repeat: repeat-x; - background-position: top left; - background-image: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQI/8QAGRABAAIDAAAAAAAAAAAAAAAAAAETERJh/8QAFAEBAAAAAAAAAAAAAAAAAAAAAP/EABQRAQAAAAAAAAAAAAAAAAAAAAD/2gAMAwEAAhEDEQA/ANV2CXcBJZ0S5kB//9k=); - border: 1px solid #ccc; - border-top: 1px solid #fff -} - -.theme-clear .pagination-bar .pagination-button, .theme-clear .pagination-bar .pagination-button-disabled, .theme-clear .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-clear .pagination-bar .separator { - border-right: 1px solid #848484 -} - -.theme-clear .kt-search-highlight { - background-color: #ff0 -} - -.theme-clear .search-field { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==) -} - -.theme-clear .king-table-region .ug-menu { - box-shadow: 0 6px 12px #717171; - background: #eee; - color: #000 -} - -.theme-clear .king-table-region .ug-menu li { - border-bottom: 1px solid #C1C1C1 -} - -.theme-clear .king-table-region .ug-menu li a, .theme-clear .king-table-region .ug-menu li label, .theme-clear .king-table-region .ug-menu li span { - color: #000 -} - -.theme-clear .king-table-region .ug-menu li a:focus, .theme-clear .king-table-region .ug-menu li a:hover, .theme-clear .king-table-region .ug-menu li label:focus, .theme-clear .king-table-region .ug-menu li label:hover, .theme-clear .king-table-region .ug-menu li span:focus, .theme-clear .king-table-region .ug-menu li span:hover { - color: #000; - background-color: #E0E0E0 -} - -.theme-clear .king-table-region .ug-menu li.open>a, .theme-clear .king-table-region .ug-menu li.open>label, .theme-clear .king-table-region .ug-menu li.open>span { - background-color: #E0E0E0 -} - -.theme-clear { - color: #000; - background-color: #FFF -} - -.theme-clear hr { - border-top: 1px solid #aaa; - border-bottom: 1px solid #fff -} - -.theme-dark .king-table-container { - border-top: 1px solid #222 -} - -.theme-dark .king-table-head { - background-color: #000 -} - -.theme-dark .filters-region { - border-bottom-color: #000 -} - -.theme-dark .king-table { - color: #DEDEDE; - background: #222; - border: none; - font-family: Sans-Serif; - font-size: 12px; - line-height: 17px; - border-bottom: 1px solid #666 -} - -.theme-dark .king-table-gallery { - background-color: #303435 -} - -.theme-dark .king-table caption { - border: 1px solid #d0d0d0; - font-weight: 700; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYF/8QAFxABAQEBAAAAAAAAAAAAAAAAABRhYv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDMu0S9+gJa7oAH/9k=) top left #373737 -} - -.theme-dark .king-table tr td.row-number { - width: 40px; - text-align: center -} - -.theme-dark .king-table a { - color: #DEDEDE -} - -.theme-dark .king-table a:focus, .theme-dark .king-table a:hover { - color: #FFF -} - -.theme-dark .king-table .king-table tr, .theme-dark .king-table .king-table-head tr { - width: 100%; - border-color: #666 -} - -.theme-dark .king-table-body tr:hover:nth-child(even), .theme-dark .king-table-body tr:hover:nth-child(odd) { - background-color: #111 -} - -.theme-dark .king-table-body tr:hover:nth-child(even).king-table-empty, .theme-dark .king-table-body tr:hover:nth-child(even).king-table-error, .theme-dark .king-table-body tr:hover:nth-child(odd).king-table-empty, .theme-dark .king-table-body tr:hover:nth-child(odd).king-table-error { - background: #222 -} - -.theme-dark .king-table .king-table-head tr { - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYF/8QAFxABAQEBAAAAAAAAAAAAAAAAABRhYv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDMu0S9+gJa7oAH/9k=) top left repeat-x #373737; - height: 18px -} - -.theme-dark .king-table tr th { - text-align: left; - border: 1px solid #666; - border-top: 1px solid #d6d6d6 -} - -.theme-dark .king-table tr td { - line-height: 15px; - border-right: 1px solid #444; - border-bottom: 1px solid #444 -} - -.theme-dark .king-table tr td.row-number, .theme-dark .king-table tr th.row-number { - border: 1px solid #666; - border-top: 1px solid #d6d6d6; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYF/8QAFxABAQEBAAAAAAAAAAAAAAAAABRhYv/EABQBAQAAAAAAAAAAAAAAAAAAAAD/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwDMu0S9+gJa7oAH/9k=) top left repeat-x #373737 -} - -.theme-dark .pagination-bar { - background-repeat: repeat-x; - background-position: top left; - background-image: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAQH/8QAGBABAQADAAAAAAAAAAAAAAAAABIBE2H/xAAVAQEBAAAAAAAAAAAAAAAAAAABAv/EABURAQEAAAAAAAAAAAAAAAAAAAAR/9oADAMBAAIRAxEAPwDIrE19FiptglvIEv/Z) -} - -.theme-dark .pagination-bar .pagination-button, .theme-dark .pagination-bar .pagination-button-disabled, .theme-dark .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-dark .pagination-bar .separator { - border-right: 1px solid #151515 -} - -.theme-dark .kt-search-highlight { - background-color: #832525 -} - -.theme-dark .search-field { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEC4Y+QhTXgAAAdFJREFUKM+lk7Gv0nAQx78t/aWkpeZBbEKDRAZjiAOvhITJYEcnJhcn48Tq4uhA4ixG2Ojw1PGR4AsmrvoHiLhBnEgwv+pAxbTN64/qubxnECFGvelyl/tc8v3eAf8Z0nbBsqwbAO4BsAEcAHgN4DHn/M0fAZZl3VFV9UjXdTDGIEkShBAIwxBxHB9xzu9uA1KbmzVNe2GaZuA4zqPhcPig1Wo9jaJoMp/Pr8uyXGeMTYIgmG0ClPPEMIz7hmGgXq8/6XQ6XUmSPAAgokmSJN8Gg0E3SZKHAE52ilGtVj/WajUiovx2j4gOGo3Gh0qlQts9+WciyxcA4HzzL0JJ0hchxHfGGPYCcrncuw0Xtp05jKLoqqqq3l5AqVQ6BoB0On2yCbEs67Kqqs8YYygUCi/32khEF5vN5vPFYnHT933EcTwBAEVR7Gw2C8YYwjD8ulqtGpzz97/Z2G63o9ls9nY6nQZRFOVTqdQ1Xdfzpml65XJ54Pv+FVmWDSHEbU3TXgVB8GnnJZ65cAlA5qx0CsDr9/uO67rd9XqdWS6XKyHEIed8ruxQ3APg7QAPAMB13W6xWPxs2/Zpr9f7u8chosxoNLo1Ho8dIlL+6fuIKL05/AMPJr+j+tXRAwAAAABJRU5ErkJggg==) -} - -.theme-dark .king-table-region .ug-menu { - box-shadow: 0 6px 12px #000; - background: #313131; - color: #DEDEDE -} - -.theme-dark .king-table-region .ug-menu li { - border-bottom: 1px solid grey -} - -.theme-dark .king-table-region .ug-menu li a, .theme-dark .king-table-region .ug-menu li label, .theme-dark .king-table-region .ug-menu li span { - color: #DEDEDE -} - -.theme-dark .king-table-region .ug-menu li a:focus, .theme-dark .king-table-region .ug-menu li a:hover, .theme-dark .king-table-region .ug-menu li label:focus, .theme-dark .king-table-region .ug-menu li label:hover, .theme-dark .king-table-region .ug-menu li span:focus, .theme-dark .king-table-region .ug-menu li span:hover { - color: #DEDEDE; - background-color: #222 -} - -.theme-dark .king-table-region .ug-menu li.open>a, .theme-dark .king-table-region .ug-menu li.open>label, .theme-dark .king-table-region .ug-menu li.open>span { - background-color: #222 -} - -.theme-dark { - color: #DEDEDE; - background-color: #000 -} - -.theme-dark a, .theme-dark a:focus, .theme-dark a:hover { - color: #DEDEDE -} - -.theme-dark .camo-btn { - color: #DADAD4 -} - -.theme-dark hr { - border-top: 1px solid #444; - border-bottom: 1px solid #000 -} - -.theme-dark input { - color: #000 -} - -.theme-dark [tabindex], .theme-dark [type=checkbox], .theme-dark input, .theme-dark select { - outline-color: #FFF!important -} - -.theme-dark .tooltip-inner { - opacity: 1; - background-color: #000 -} - -.theme-olive .king-table { - color: #1c2706; - background: #bebd63; - border: none; - font-family: Sans-Serif; - font-size: 12px; - line-height: 17px; - border-bottom: 1px solid #475f15 -} - -.theme-olive .filters-region { - background-color: #CBDF30 -} - -.theme-olive .king-table-gallery { - background-color: #233107; - color: #DCF043 -} - -.theme-olive .king-table-gallery li>span { - border-bottom: 1px solid #4C5D2C -} - -.theme-olive .king-table caption { - border: 1px solid #475f15; - font-weight: 700; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAQGCP/EABwQAQACAQUAAAAAAAAAAAAAAAABFGECBFGR0f/EABcBAAMBAAAAAAAAAAAAAAAAAAEDBQf/xAAXEQEBAQEAAAAAAAAAAAAAAAAAEQIV/9oADAMBAAIRAxEAPwDSlrIr1rdcaOp9GK9vZsTq0YARIL//2Q==) top left #fff -} - -.theme-olive .king-table tr td.row-number { - width: 40px; - text-align: center; - color: #475f15 -} - -.theme-olive .king-table a { - color: #000 -} - -.theme-olive .king-table a:hover { - color: #C00 -} - -.theme-olive .king-table .king-table tr, .theme-olive .king-table .king-table-head tr { - width: 100% -} - -.theme-olive .king-table-body tr:hover:nth-child(even), .theme-olive .king-table-body tr:hover:nth-child(odd) { - background-color: #e6f0a3 -} - -.theme-olive .king-table-body tr:hover:nth-child(even).king-table-empty, .theme-olive .king-table-body tr:hover:nth-child(even).king-table-error, .theme-olive .king-table-body tr:hover:nth-child(odd).king-table-empty, .theme-olive .king-table-body tr:hover:nth-child(odd).king-table-error { - background: #bebd63 -} - -.theme-olive .king-table .king-table-head tr { - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAQGCP/EABwQAQACAQUAAAAAAAAAAAAAAAABFGECBFGR0f/EABcBAAMBAAAAAAAAAAAAAAAAAAEDBQf/xAAXEQEBAQEAAAAAAAAAAAAAAAAAEQIV/9oADAMBAAIRAxEAPwDSlrIr1rdcaOp9GK9vZsTq0YARIL//2Q==) top left repeat-x #dbf043; - height: 18px -} - -.theme-olive .king-table tr th { - text-align: left; - border: 1px solid #475f15 -} - -.theme-olive .king-table tr td { - line-height: 15px; - border-right: 1px solid #475f15; - border-bottom: 1px solid #475f15 -} - -.theme-olive .king-table tr td.row-number, .theme-olive .king-table tr th.row-number { - border: 1px solid #475f15; - border-top: 1px solid #475f15; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAWAAEDASIAAhEBAxEB/8QAFwABAAMAAAAAAAAAAAAAAAAAAAUGCP/EABoQAQACAwEAAAAAAAAAAAAAAAACEwQUUZH/xAAXAQADAQAAAAAAAAAAAAAAAAABAwUH/8QAFxEBAAMAAAAAAAAAAAAAAAAAAAMSFf/aAAwDAQACEQMRAD8A0ptiv35PI+DE9qQ2qQogAjC//9k=) top left repeat-x #dbf043 -} - -.theme-olive .pagination-bar { - background-repeat: repeat-x; - background-position: top left; - background-image: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFwABAQEBAAAAAAAAAAAAAAAAAAUECP/EAB0QAQABAwUAAAAAAAAAAAAAAAABAhNhAxQVU5H/xAAXAQADAQAAAAAAAAAAAAAAAAACAwYH/8QAGBEBAAMBAAAAAAAAAAAAAAAAABESFWH/2gAMAwEAAhEDEQA/AOlr+RE5DS7J8kY5s9Mqz7fAqW6ROQJ//9k=); - border: 1px solid #455b1b -} - -.theme-olive .pagination-bar .pagination-button, .theme-olive .pagination-bar .pagination-button-disabled, .theme-olive .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-olive .pagination-bar .separator { - border-right: 1px solid #455b1b -} - -.theme-olive .kt-search-highlight { - background-color: #ff0 -} - -.theme-olive .king-table-gallery .kt-search-highlight { - background-color: #792323 -} - -.theme-olive .search-field { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcaBygLIDCvHQAAAdFJREFUKM+lk81rE1EUxc/LTCbjZGJTCZkqhZSSaMHgxEVdSTMrFUTcBJepEWkWCvoPSHEhrgSx7kQo2kWhSCsU6aIL3YgI1oqbYlOwi5aMGGw7qWnSZI4bI0Pawa+3epx37+8+zr0X+M8jOoWUoWcltm5KaGUEGG1CftkS0v1lu/rqt4CUoQ/Hg/XxmBbAAVkgIIDtXeLrdxeVhjy+9KVW8P1KytCzVkJhwdSc6ZHMXZIWSevN7Qs3CqbmnE+GmDL0i76Aof7IbD6tcvKKeYdkT1snGX196+z1fFpltk/76Au4dDy8lk+r9CZ7IddORZdzAyo73wLtiyLcgwAghCjvMUqIje1dupq8t/AvgNEded/2ojMoaUTMaq1+NBRSyr6AY4nDUwAQVxrPvZCkEUkcCjafaDLQfyQ269tGkrHRM71PS+uVc6ubLXxrBBYBICy5mUSXBE0G7Bq2VqrBoZLtfNh3DkgOzBRPDs8vfs7ZWztJAOgOK+UTffG5hdJ6rt509ZUNd7PSDGXbELGP4z0AegHoP6UdAOWFsaL18PHEmAdilmxn9Y9nnqT+7sHI5YKpOcXB6KdHV08bf704JPWlZ/dya29fWCTlf9o+kqo3+Qdpar4Yro3HOgAAAABJRU5ErkJggg==) -} - -.theme-olive .king-table-region .ug-menu { - box-shadow: 0 6px 12px #475F15; - background: #DDE979; - color: #455b1b -} - -.theme-olive .king-table-region .ug-menu li { - border-bottom: 1px solid #BEBD63 -} - -.theme-olive .king-table-region .ug-menu li a, .theme-olive .king-table-region .ug-menu li label, .theme-olive .king-table-region .ug-menu li span { - color: #455b1b -} - -.theme-olive .king-table-region .ug-menu li a:focus, .theme-olive .king-table-region .ug-menu li a:hover, .theme-olive .king-table-region .ug-menu li label:focus, .theme-olive .king-table-region .ug-menu li label:hover, .theme-olive .king-table-region .ug-menu li span:focus, .theme-olive .king-table-region .ug-menu li span:hover { - color: #455b1b; - background-color: #e6f0a3 -} - -.theme-olive .king-table-region .ug-menu li.open>a, .theme-olive .king-table-region .ug-menu li.open>label, .theme-olive .king-table-region .ug-menu li.open>span { - background-color: #e6f0a3 -} - -.theme-olive { - color: #455b1b; - background-color: #233107 -} - -.theme-olive .camo-btn { - color: #455b1b -} - -.theme-olive [tabindex], .theme-olive [type=checkbox], .theme-olive input, .theme-olive select { - outline-color: #25150a!important -} - -.theme-midnight [tabindex], .theme-midnight [type=checkbox], .theme-midnight input, .theme-midnight select, .theme-ultramarine [tabindex], .theme-ultramarine [type=checkbox], .theme-ultramarine input, .theme-ultramarine select { - outline-color: #c4feff!important -} - -.theme-olive hr { - border-top: 1px solid #afc423; - border-bottom: 1px solid #e3ee9f -} - -.theme-bronze .king-table-container { - border-top: 1px solid #533e29 -} - -.theme-bronze .filters-region { - background-color: #FFA92D; - border-bottom-color: #FFA92D -} - -.theme-bronze .king-table { - background: #DA832C; - border: none; - font-family: Sans-Serif; - font-size: 12px; - line-height: 17px; - border-bottom: 1px solid #533e29 -} - -.theme-bronze .king-table-gallery { - background-color: #3A1700; - color: #FFA53D -} - -.theme-bronze .king-table-gallery li>span { - border-bottom: 1px solid #533E29 -} - -.theme-bronze .king-table caption { - border: 1px solid #533e29; - font-weight: 700; - background: url(data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAABmJLR0QA3wB5ABSzHNRVAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QkaFRIaz7uY6QAAAENJREFUCNdly7EJgFAQBNG5xUxswf4Tq7ICBUN3Df5pYvYYGLytURIkFobKEwIQdb2SW87cOvYT2e7NNqrU1/7iZrwPFLYoooBe/o4AAAAASUVORK5CYII=) top left #fff -} - -.theme-bronze .king-table tr td.row-number { - width: 40px; - text-align: center -} - -.theme-bronze .king-table a { - color: #000 -} - -.theme-bronze .king-table a:hover { - color: #C00 -} - -.theme-bronze .king-table .king-table tr, .theme-bronze .king-table .king-table-head tr { - width: 100%; - border-color: #483419 -} - -.theme-bronze .king-table-body tr:hover:nth-child(even), .theme-bronze .king-table-body tr:hover:nth-child(odd) { - background-color: #ffecb5 -} - -.theme-bronze .king-table-body tr:hover:nth-child(even).king-table-empty, .theme-bronze .king-table-body tr:hover:nth-child(even).king-table-error, .theme-bronze .king-table-body tr:hover:nth-child(odd).king-table-empty, .theme-bronze .king-table-body tr:hover:nth-child(odd).king-table-error { - background: #DA832C -} - -.theme-bronze .king-table .king-table-head tr { - height: 18px; - background: url(data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAABmJLR0QA3wB5ABSzHNRVAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QkaFRIaz7uY6QAAAENJREFUCNdly7EJgFAQBNG5xUxswf4Tq7ICBUN3Df5pYvYYGLytURIkFobKEwIQdb2SW87cOvYT2e7NNqrU1/7iZrwPFLYoooBe/o4AAAAASUVORK5CYII=) top left repeat-x #E27D15; - border-bottom: 1px solid #000 -} - -.theme-bronze .king-table tr th { - text-align: left; - border-top: 1px solid #efb77c; - border-right: 1px solid #000 -} - -.theme-bronze .king-table tr td { - line-height: 15px; - border-right: 1px solid #483419; - border-bottom: 1px solid #483419 -} - -.theme-bronze .king-table tr td.row-number, .theme-bronze .king-table tr th.row-number { - background: url(data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAYCAYAAAA7zJfaAAAABmJLR0QA3wB5ABSzHNRVAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QkaFRIaz7uY6QAAAENJREFUCNdly7EJgFAQBNG5xUxswf4Tq7ICBUN3Df5pYvYYGLytURIkFobKEwIQdb2SW87cOvYT2e7NNqrU1/7iZrwPFLYoooBe/o4AAAAASUVORK5CYII=) top left repeat-x #e27d15 -} - -.theme-bronze .pagination-bar { - background-repeat: repeat-x; - background-position: top left; - background-image: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAGAABAAMBAAAAAAAAAAAAAAAAAAQFBgf/xAAeEAEAAAUFAAAAAAAAAAAAAAAAAQIEE2EFFVWU0f/EABYBAQEBAAAAAAAAAAAAAAAAAAcDBP/EABkRAAIDAQAAAAAAAAAAAAAAAAASAQJREf/aAAwDAQACEQMRAD8A6Ps+kcVQ9eTwTgAPbZFZp0yV7Irrscjchfh//9k=) -} - -.theme-bronze .pagination-bar .pagination-button, .theme-bronze .pagination-bar .pagination-button-disabled, .theme-bronze .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-bronze .pagination-bar .separator { - border-right: 1px solid #000 -} - -.theme-bronze .kt-search-highlight { - background-color: #ff0 -} - -.theme-bronze .king-table-gallery .kt-search-highlight { - background-color: #000 -} - -.theme-bronze .search-field { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcaBygLIDCvHQAAAdFJREFUKM+lk81rE1EUxc/LTCbjZGJTCZkqhZSSaMHgxEVdSTMrFUTcBJepEWkWCvoPSHEhrgSx7kQo2kWhSCsU6aIL3YgI1oqbYlOwi5aMGGw7qWnSZI4bI0Pawa+3epx37+8+zr0X+M8jOoWUoWcltm5KaGUEGG1CftkS0v1lu/rqt4CUoQ/Hg/XxmBbAAVkgIIDtXeLrdxeVhjy+9KVW8P1KytCzVkJhwdSc6ZHMXZIWSevN7Qs3CqbmnE+GmDL0i76Aof7IbD6tcvKKeYdkT1snGX196+z1fFpltk/76Au4dDy8lk+r9CZ7IddORZdzAyo73wLtiyLcgwAghCjvMUqIje1dupq8t/AvgNEded/2ojMoaUTMaq1+NBRSyr6AY4nDUwAQVxrPvZCkEUkcCjafaDLQfyQ269tGkrHRM71PS+uVc6ubLXxrBBYBICy5mUSXBE0G7Bq2VqrBoZLtfNh3DkgOzBRPDs8vfs7ZWztJAOgOK+UTffG5hdJ6rt509ZUNd7PSDGXbELGP4z0AegHoP6UdAOWFsaL18PHEmAdilmxn9Y9nnqT+7sHI5YKpOcXB6KdHV08bf704JPWlZ/dya29fWCTlf9o+kqo3+Qdpar4Yro3HOgAAAABJRU5ErkJggg==) -} - -.theme-bronze .king-table-region .ug-menu { - box-shadow: 0 6px 12px #691010; - background: #FFA92D; - color: #3a1700 -} - -.theme-bronze .king-table-region .ug-menu li { - border-bottom: 1px solid #4A1111 -} - -.theme-bronze .king-table-region .ug-menu li a, .theme-bronze .king-table-region .ug-menu li label, .theme-bronze .king-table-region .ug-menu li span { - color: #3a1700 -} - -.theme-bronze .king-table-region .ug-menu li a:focus, .theme-bronze .king-table-region .ug-menu li a:hover, .theme-bronze .king-table-region .ug-menu li label:focus, .theme-bronze .king-table-region .ug-menu li label:hover, .theme-bronze .king-table-region .ug-menu li span:focus, .theme-bronze .king-table-region .ug-menu li span:hover { - color: #3a1700; - background-color: #ffecb5 -} - -.theme-bronze .king-table-region .ug-menu li.open>a, .theme-bronze .king-table-region .ug-menu li.open>label, .theme-bronze .king-table-region .ug-menu li.open>span { - background-color: #ffecb5 -} - -.theme-bronze { - color: #000; - background-color: #3a1700 -} - -.theme-bronze hr { - border-top: 1px solid #a82d00; - border-bottom: 1px solid #ffab25 -} - -.theme-ultramarine .king-table-container { - border-top: 1px solid #071436 -} - -.theme-ultramarine .filters-region { - background-color: #275E8E; - border-bottom: 1px solid #275E8E -} - -.theme-ultramarine .king-table { - background: #0b2258; - border: none; - font-family: Sans-Serif; - font-size: 12px; - line-height: 17px; - border-bottom: 1px solid #071436 -} - -.theme-ultramarine .king-table tr { - color: #BEE0FF -} - -.theme-ultramarine .king-table-gallery { - background-color: #05385A; - color: #7DB3EF -} - -.theme-ultramarine .king-table-gallery li>span { - border-bottom: 1px solid #000 -} - -.theme-ultramarine .king-table caption { - border: 1px solid #071436; - font-weight: 700; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYB/8QAGRABAQEAAwAAAAAAAAAAAAAAAAEUUVKh/8QAFgEBAQEAAAAAAAAAAAAAAAAABwED/8QAFhEBAQEAAAAAAAAAAAAAAAAAABES/9oADAMBAAIRAxEAPwDNt59ExuvaBBH2kxvoCMa//9k=) top left #fff -} - -.theme-ultramarine .king-table tr td.row-number { - width: 40px; - text-align: center; - color: #071436 -} - -.theme-ultramarine .king-table a, .theme-ultramarine .king-table a:focus, .theme-ultramarine .king-table a:hover { - color: #BEE0FF -} - -.theme-ultramarine .king-table a:hover { - color: #C00 -} - -.theme-ultramarine .king-table .king-table tr, .theme-ultramarine .king-table .king-table-head tr { - width: 100%; - border-color: #483419 -} - -.theme-ultramarine .king-table .king-table tr { - color: #5498d2 -} - -.theme-ultramarine .king-table-body tr:hover:nth-child(even), .theme-ultramarine .king-table-body tr:hover:nth-child(odd) { - background-color: #071436 -} - -.theme-ultramarine .king-table-body tr:hover:nth-child(even).king-table-empty, .theme-ultramarine .king-table-body tr:hover:nth-child(even).king-table-error, .theme-ultramarine .king-table-body tr:hover:nth-child(odd).king-table-empty, .theme-ultramarine .king-table-body tr:hover:nth-child(odd).king-table-error { - background: #0b2258 -} - -.theme-ultramarine .king-table .king-table-head tr, .theme-ultramarine .king-table tr td.row-number, .theme-ultramarine .king-table tr th.row-number { - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYB/8QAGRABAQEAAwAAAAAAAAAAAAAAAAEUUVKh/8QAFgEBAQEAAAAAAAAAAAAAAAAABwED/8QAFhEBAQEAAAAAAAAAAAAAAAAAABES/9oADAMBAAIRAxEAPwDNt59ExuvaBBH2kxvoCMa//9k=) top left repeat-x #07578c -} - -.theme-ultramarine .king-table .king-table-head tr { - height: 18px -} - -.theme-ultramarine .king-table tr th { - text-align: left; - border: 1px solid #09165a; - border-top: 1px solid #6080bd -} - -.theme-ultramarine .king-table tr td { - line-height: 15px; - border-right: 1px solid #09165a; - border-bottom: 1px solid #09165a -} - -.theme-ultramarine .pagination-bar { - background-repeat: repeat-x; - background-position: top left; - background-image: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAeAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAb/xAAcEAEAAQQDAAAAAAAAAAAAAAAAAgEUFWFRYqH/xAAWAQEBAQAAAAAAAAAAAAAAAAAGAAT/xAAVEQEBAAAAAAAAAAAAAAAAAAAAEv/aAAwDAQACEQMRAD8AscjHkSmR7eh+D2kL+uxKXs9iZbf/2Q==); - border: 1px solid #1e2d9e -} - -.theme-ultramarine .pagination-bar .pagination-button, .theme-ultramarine .pagination-bar .pagination-button-disabled, .theme-ultramarine .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-ultramarine .pagination-bar .separator { - border-right: 1px solid #071436 -} - -.theme-ultramarine .kt-search-highlight { - background-color: #630404 -} - -.theme-ultramarine .search-field { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAPCAYAAADtc08vAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcaByk3FkTi2wAAAcdJREFUKM+lkzFoE2EUx//fd/FyXi8lV47LlQSqklinJu7S3KQVUZfgmBgQOyjoqouTdBKEunUpbQfBQYUiDoK6iItVcak2BStUUjHGeg1eSu7+DhoJbQ+1vunj/3g/3vt/7wH/GWKrYJi5YhAql4NQKZAiGVM6TxQZ3NxoLj39I8Awc5V2aE9L1YKQewFIMGwh3PyMGBrT39cXq5GtGGauqJou9XTVK4zdnSDpknRPnnt+SU9Xvbh1goaZOx0JSNij85pTZv7o7eskna5OMnms8uyi5pSpW8U3kYC+wTOrmlNmb3EvJLn/wpJml7g1J7uPEGo/AAgh6tuMEuIrg1YIqSMSkOhPvex6sW08M5tv+xsHVTVejwQMZobvAMAm7fu9kMRAdqiDgRlIHVbqwHzkN5K0MiPXZhufamOBvwLJ5qufo/UVFG0IkDrQWfu2J1ge9Zq11zvuAclDh4/fq7x/+6jkt9ayAKBqZt1Ojzz8+GGhFHbaRugvr8dlo9iFiB0cdwBkABi/JB9Affzqgjs3c2vyN0Rp5L0vtZW/3nmSxvkrL87q6aqX3Df+7sipqdQ/Hw5J48bUYunB41WXZGxX10dS6y3+AfpUvSB00xFiAAAAAElFTkSuQmCC) -} - -.theme-ultramarine .king-table-region .ug-menu { - box-shadow: 0 6px 12px #081125; - background: #619CD6; - color: #000 -} - -.theme-ultramarine .king-table-region .ug-menu li { - border-bottom: 1px solid #2873AC -} - -.theme-ultramarine .king-table-region .ug-menu li a, .theme-ultramarine .king-table-region .ug-menu li label, .theme-ultramarine .king-table-region .ug-menu li span { - color: #455b1b -} - -.theme-ultramarine .king-table-region .ug-menu li a:focus, .theme-ultramarine .king-table-region .ug-menu li a:hover, .theme-ultramarine .king-table-region .ug-menu li label:focus, .theme-ultramarine .king-table-region .ug-menu li label:hover, .theme-ultramarine .king-table-region .ug-menu li span:focus, .theme-ultramarine .king-table-region .ug-menu li span:hover { - color: #455b1b; - background-color: #7DB3EF -} - -.theme-ultramarine .king-table-region .ug-menu li.open>a, .theme-ultramarine .king-table-region .ug-menu li.open>label, .theme-ultramarine .king-table-region .ug-menu li.open>span { - background-color: #7DB3EF -} - -.theme-ultramarine { - color: #071436; - background-color: #010004 -} - -.theme-ultramarine .camo-btn { - color: #071436 -} - -.theme-ultramarine hr { - border-top: 1px solid #09165a; - border-bottom: 1px solid #5252b3 -} - -.theme-midnight .king-table-container { - border-top: 1px solid #222 -} - -.theme-midnight .filters-region { - border-bottom-color: #000 -} - -.theme-midnight .king-table { - color: #c4feff; - background: #000; - border: none; - font-family: Sans-Serif; - font-size: 12px; - line-height: 17px; - border-bottom: 1px solid #666 -} - -.theme-midnight .king-table caption { - border: 1px solid #d0d0d0; - font-weight: 700; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAYAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAcF/8QAHhABAAAFBQAAAAAAAAAAAAAAAAEDFBUXUVVipOL/xAAVAQEBAAAAAAAAAAAAAAAAAAABA//EABYRAQEBAAAAAAAAAAAAAAAAAAASAf/aAAwDAQACEQMRAD8A27xyEHylM2ns+Q0lOpVUQ1ACr//Z) top left repeat-x #000 -} - -.theme-midnight .king-table tr td.row-number { - width: 40px; - text-align: center -} - -.theme-midnight .king-table a { - color: #00becf -} - -.theme-midnight .king-table a:hover { - color: #FFF -} - -.theme-midnight .king-table .king-table tr, .theme-midnight .king-table .king-table-head tr { - width: 100%; - border-color: #333 -} - -.theme-midnight .king-table-body tr:hover:nth-child(even), .theme-midnight .king-table-body tr:hover:nth-child(odd) { - background-color: #06002a -} - -.theme-midnight .king-table-body tr:hover:nth-child(even).king-table-empty, .theme-midnight .king-table-body tr:hover:nth-child(even).king-table-error, .theme-midnight .king-table-body tr:hover:nth-child(odd).king-table-empty, .theme-midnight .king-table-body tr:hover:nth-child(odd).king-table-error { - background: #000 -} - -.theme-midnight .king-table .king-table-head tr { - background-color: #000; - border-bottom: 1px solid #222; - height: 18px -} - -.theme-midnight .king-table tr th { - text-align: left; - border-top: 1px solid #222 -} - -.theme-midnight .king-table tr td { - line-height: 15px; - border-right: 1px solid #222; - border-bottom: 1px solid #222 -} - -.theme-midnight .king-table tr td.row-number, .theme-midnight .king-table tr th.row-number { - border-top: 1px solid #222; - background: url(data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAXwBfAAD/2wBDAAUDBAQEAwUEBAQFBQUGBwwIBwcHBw8LCwkMEQ8SEhEPERETFhwXExQaFRERGCEYGh0dHx8fExciJCIeJBweHx7/2wBDAQUFBQcGBw4ICA4eFBEUHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh4eHh7/wAARCAAWAAEDASIAAhEBAxEB/8QAFgABAQEAAAAAAAAAAAAAAAAAAAYH/8QAGBABAAMBAAAAAAAAAAAAAAAAAAIUYmH/xAAUAQEAAAAAAAAAAAAAAAAAAAAC/8QAFREBAQAAAAAAAAAAAAAAAAAAABH/2gAMAwEAAhEDEQA/AMTv6Erf0HRiWuT6ABP/2Q==) top left repeat-x #000 -} - -.theme-midnight .pagination-bar { - background-repeat: repeat-x; - background-position: top left; - background-image: url(data:image/jpeg;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAAeCAYAAADtlXTHAAAABmJLR0QAigA6AAVbg4eFAAAACXBIWXMAAA6cAAAOnAEHlFPdAAAAB3RJTUUH3QcKDRQh1fbNfQAAAElJREFUCNdVikEKwDAMwxRD2fP3gLGPxinZYWWsFyEbcV53q6pQpZGdC+ncP6Ny8sZretmchnGMFoCC4LUfAhQdiGhEg/i62OIHIVwwSHkNyBEAAAAASUVORK5CYII=) -} - -.theme-midnight .pagination-bar .pagination-button, .theme-midnight .pagination-bar .pagination-button-disabled, .theme-midnight .pagination-bar .separator { - border: 1px solid transparent -} - -.theme-midnight .pagination-bar .separator { - border-right: 1px solid #1C3131 -} - -.theme-midnight .kt-search-highlight { - background-color: #3a3ae4 -} - -.theme-midnight .search-field { - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAOCAYAAAAmL5yKAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcZEDE7ljUssgAAAeNJREFUKM+lk81PE1EUxc+b99op40SKfHQIJkZDAU0DmGg1fsFCie5YdEnSEP8BWGgM6A5M40LUrlFUdm4gcWHAhZgIbtS6IsRGQ0LjzCSUEZqinY/rQoY0xUaNd3Vz8u7v5p13HvCfxSqFvtSdHrWlZUgOh7t5MBgumuarQi53b+7G9YU/Aq5M3E9GTp6YQlAGBP8lOi5Q+gHrU3ZqZjA5WAng5Zubz56Z8UKhAj9Qd/fhsaO3+pu1x4tCZArb2+dq6hviWnt7Jjs/t1IOEH5T2xa9BkWBUGoeTB45nGaM6QBARJlhItcyjHRdLDYGYLYcIPlNSNOOA8BkNLo7DACMMWtCi0w7tp2Vm5pilVfYBbBAYP/OgL7HKMYs2LYHzlEV4HreB9+LykOXxm93CVlucx1HrwoQsvwMACLx+Gw55OLY+KH6zs4n4BwEPK/6jETUMPDu/dOAJF1GsYiiYWYAQGls7MY+BeAc7lZhU3+9cGF+dOTjb3NARB1XP39JlvL5hJCkVgBwiXQWlF/ALiUkxlRnw/pmvF3q8SF7kkhEGoCDANQd6TsAPWWavctrubQP0ZcWu17eHF1lf5t5IlJTpplYXsulPcf5GiA6/+j0KeOfPg4RqdPr+cSbza1eIhIA8BOAQ7mCZoIs4QAAAABJRU5ErkJggg==) -} - -.theme-midnight .king-table-container .preloader-mask { - opacity: .5; - background-color: #091431 -} - -.theme-midnight .king-table-region .ug-menu { - box-shadow: 0 6px 12px #4347B3; - background: #111; - color: #c4feff -} - -.theme-midnight .king-table-region .ug-menu li { - border-bottom: 1px solid #000 -} - -.theme-midnight .king-table-region .ug-menu li a, .theme-midnight .king-table-region .ug-menu li label, .theme-midnight .king-table-region .ug-menu li span { - color: #c4feff -} - -.theme-midnight .king-table-region .ug-menu li a:focus, .theme-midnight .king-table-region .ug-menu li a:hover, .theme-midnight .king-table-region .ug-menu li label:focus, .theme-midnight .king-table-region .ug-menu li label:hover, .theme-midnight .king-table-region .ug-menu li span:focus, .theme-midnight .king-table-region .ug-menu li span:hover { - color: #c4feff; - background-color: #000; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAAAWCAYAAAASPXQbAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcMEw8zvKqmCQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAkklEQVRo3u3aQRLCIAxA0R/Bo3s2D1U6uMEpIsXu3Pw3wzQNIU33BMDjWTOQgNxWauve5fv9vubIBYn6sT8/F2Tqsu8qvnqun3+szcBt+L9Z7wLs7XkW97n3+06wUZf1v3rN+37n5nFQ2ve3of/YoxDsJ7PO5pAkSZIkSZIkSZIkSZIkSZL0RwFeAsdL4Jcvgb8Adb+Yn8Y8eNcAAAAASUVORK5CYII=); - background-repeat: no-repeat; - background-position: center -} - -.theme-midnight .king-table-region .ug-menu li.open>a, .theme-midnight .king-table-region .ug-menu li.open>label, .theme-midnight .king-table-region .ug-menu li.open>span { - background-color: #000; - background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAIwAAAAWCAYAAAASPXQbAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3QcMEw8zvKqmCQAAAB1pVFh0Q29tbWVudAAAAAAAQ3JlYXRlZCB3aXRoIEdJTVBkLmUHAAAAkklEQVRo3u3aQRLCIAxA0R/Bo3s2D1U6uMEpIsXu3Pw3wzQNIU33BMDjWTOQgNxWauve5fv9vubIBYn6sT8/F2Tqsu8qvnqun3+szcBt+L9Z7wLs7XkW97n3+06wUZf1v3rN+37n5nFQ2ve3of/YoxDsJ7PO5pAkSZIkSZIkSZIkSZIkSZL0RwFeAsdL4Jcvgb8Adb+Yn8Y8eNcAAAAASUVORK5CYII=); - background-repeat: no-repeat; - background-position: center -} - -.theme-midnight { - color: #c4feff; - background-color: #000 -} - -.theme-midnight .camo-btn { - color: #c4feff -} - -.theme-midnight input, .theme-midnight select, .theme-midnight textarea { - background-color: #000; - border-color: #333; - color: #c4feff -} - -.theme-midnight hr { - border-top: 1px solid #02232a; - border-bottom: 1px solid #106274 -} - -.king-table-container .preloader-mask { - height: 100%; - width: 100%; - min-height: 300px; - position: absolute; - top: 0; - opacity: .5; - background-color: #fff -} - -.king-table-container .preloader-mask .preloader-icon { - position: absolute; - background-repeat: no-repeat; - background-position: 50% 50%; - height: 100%; - width: 100% -} - -.king-table-region *, .king-table-region :after, .king-table-region :before { - box-sizing: content-box; - -webkit-box-sizing: content-box; - -moz-box-sizing: content-box -} - -.king-table-region .btn { - font-size: 12px -} - -.king-table-region .camo-btn { - background: 0 0; - border: none; - padding: 3px 10px; - font-style: italic; - cursor: pointer -} - -.king-table-region .camo-btn:focus, .king-table-region .camo-btn:hover { - text-decoration: underline -} - -.king-table-region .uneditable-input, .king-table-region input[type=text], .king-table-region input[type=week], .king-table-region input[type=number], .king-table-region input[type=email], .king-table-region input[type=url], .king-table-region input[type=search], .king-table-region input[type=tel], .king-table-region input[type=color], .king-table-region input[type=password], .king-table-region input[type=datetime], .king-table-region input[type=datetime-local], .king-table-region input[type=date], .king-table-region input[type=month], .king-table-region input[type=time], .king-table-region select, .king-table-region textarea { - margin-bottom: 10px; - background-color: #fff; - border: 1px solid #ccc; - -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - box-shadow: inset 0 1px 1px rgba(0, 0, 0, .075); - -webkit-transition: border linear .2s, box-shadow linear .2s; - -moz-transition: border linear .2s, box-shadow linear .2s; - -o-transition: border linear .2s, box-shadow linear .2s; - transition: border linear .2s, box-shadow linear .2s; - display: inline-block; - padding: 2px 4px; - color: #555; - vertical-align: middle; - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - border-radius: 4px; - font-size: 11px -} - -.king-table-region .king-table-caption, .king-table-region caption { - text-align: left; - padding: 5px; - font-weight: 400; - font-size: 12px; - border-bottom: 1px solid #ccc; - line-height: 20px; - border-top: 1px solid #ccc -} - -.king-table-head { - height: 19px; - white-space: nowrap -} - -.king-table-body { - padding: 0; - margin: 0 -} - -.king-table-gallery { - list-style-type: none; - padding: 0; - margin: 0; - font-size: 12px -} - -.king-table-gallery>ul>li { - float: left; - padding: 10px 20px; - list-style: none; - margin: 0 -} - -.king-table-gallery>ul>li>span { - display: block; - padding: 3px 0; - border-bottom: 1px solid #E0E0E0; - cursor: default -} - -.king-table-gallery>ul>li .item-number { - font-weight: 700 -} - -.king-table-gallery .break { - clear: both -} - -.king-table-empty, .king-table-error { - padding: 5px 6px; - font-size: 12px -} - -.king-table { - width: 100%; - cursor: default; - font-size: 12px; - border-collapse: collapse -} - -.king-table .loading-info { - vertical-align: middle; - padding: 5px 6px -} - -.king-table .loading-text { - display: inline-block; - vertical-align: top; - margin-top: 2px -} - -.king-table .mini-loader { - background-image: url(../img/tiny-loader.gif); - background-repeat: no-repeat; - background-position: top; - background-size: 16px 16px; - display: inline-block; - width: 20px; - height: 20px; - margin: 4px -} - -.king-table tr td, .king-table tr th { - font-size: 12px; - padding-left: 5px -} - -.king-table tr td.detail-link a, .king-table tr th.detail-link a { - padding: 4px -} - -.king-table tr th { - text-align: left; - font-family: Verdana, Tahoma, Helvetica, Geneva -} - -.king-table tr td { - padding: 5px 10px 5px 5px -} - -.king-table.special-order .order-asc, .king-table.special-order .order-desc { - display: none -} - -.king-table .king-table-head tr .order-desc { - background-repeat: no-repeat; - background-position: -60px 0; - visibility: hidden -} - -.king-table .king-table-go-to-cell { - width: 30px -} - -.king-table .king-table-head tr .order-asc { - background-repeat: no-repeat; - background-position: 5px 0; - visibility: hidden -} - -.king-table .king-table-head th.current-sort .order-asc, .king-table .king-table-head th.current-sort .order-desc { - visibility: visible -} - -.king-table.row-number-no-bgimg .row-number { - background-image: none!important -} - -.king-table-head th-container { - position: relative; - padding-left: 4px -} - -.king-table-head th .smart-column-options { - background-repeat: no-repeat; - background-position: -194px -112px; - position: absolute; - right: 0; - top: 0 -} - -.king-table-head th { - position: relative -} - -.king-table-head th .resize-handler { - cursor: col-resize; - position: absolute; - right: -1px; - top: -1px; - width: 7px; - height: 18px -} - -.king-table-head th-container.tools-cell { - text-align: center; - padding-left: 0; - cursor: pointer -} - -.kt-search-active.kt-search-active .kt-sort-glyph { - display: none!important -} - -.kt-filters { - padding: 0 15px -} - -.kt-filters.kt-expandable { - display: none -} - -.kt-filters.kt-expandable.kt-open { - display: block -} - -@font-face { - font-family: Icons; - src: url(fonts/open-iconic.eot); - src: url(fonts/open-iconic.eot?#iconic-sm) format('embedded-opentype'), url(fonts/open-iconic.woff) format('woff'), url(fonts/open-iconic.ttf) format('truetype'), url(fonts/open-iconic.otf) format('opentype'), url(fonts/open-iconic.svg#iconic-sm) format('svg'); - font-weight: 400; - font-style: normal -} - -.oi[data-glyph].oi-text-replace { - font-size: 0; - line-height: 0 -} - -.oi[data-glyph].oi-text-replace:before { - width: 1em; - text-align: center -} - -.oi[data-glyph]:before { - position: relative; - top: 1px; - font-family: Icons; - display: inline-block; - speak: none; - line-height: 1; - vertical-align: baseline; - font-weight: 400; - font-style: normal; - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale -} - -.oi[data-glyph]:empty:before { - width: 1em; - text-align: center; - box-sizing: content-box -} - -.oi[data-glyph].oi-align-left:before { - text-align: left -} - -.oi[data-glyph].oi-align-right:before { - text-align: right -} - -.oi[data-glyph].oi-align-center:before { - text-align: center -} - -.oi[data-glyph].oi-flip-horizontal:before { - -webkit-transform: scale(-1, 1); - -ms-transform: scale(-1, 1); - transform: scale(-1, 1) -} - -.oi[data-glyph].oi-flip-vertical:before { - -webkit-transform: scale(1, -1); - -ms-transform: scale(-1, 1); - transform: scale(1, -1) -} - -.oi[data-glyph].oi-flip-horizontal-vertical:before { - -webkit-transform: scale(-1, -1); - -ms-transform: scale(-1, 1); - transform: scale(-1, -1) -} - -.oi[data-glyph=account-login]:before { - content: '\e000' -} - -.oi[data-glyph=account-logout]:before { - content: '\e001' -} - -.oi[data-glyph=action-redo]:before { - content: '\e002' -} - -.oi[data-glyph=action-undo]:before { - content: '\e003' -} - -.oi[data-glyph=align-center]:before { - content: '\e004' -} - -.oi[data-glyph=align-left]:before { - content: '\e005' -} - -.oi[data-glyph=align-right]:before { - content: '\e006' -} - -.oi[data-glyph=aperture]:before { - content: '\e007' -} - -.oi[data-glyph=arrow-bottom]:before { - content: '\e008' -} - -.oi[data-glyph=arrow-circle-bottom]:before { - content: '\e009' -} - -.oi[data-glyph=arrow-circle-left]:before { - content: '\e00a' -} - -.oi[data-glyph=arrow-circle-right]:before { - content: '\e00b' -} - -.oi[data-glyph=arrow-circle-top]:before { - content: '\e00c' -} - -.oi[data-glyph=arrow-left]:before { - content: '\e00d' -} - -.oi[data-glyph=arrow-right]:before { - content: '\e00e' -} - -.oi[data-glyph=arrow-thick-bottom]:before { - content: '\e00f' -} - -.oi[data-glyph=arrow-thick-left]:before { - content: '\e010' -} - -.oi[data-glyph=arrow-thick-right]:before { - content: '\e011' -} - -.oi[data-glyph=arrow-thick-top]:before { - content: '\e012' -} - -.oi[data-glyph=arrow-top]:before { - content: '\e013' -} - -.oi[data-glyph=audio-spectrum]:before { - content: '\e014' -} - -.oi[data-glyph=audio]:before { - content: '\e015' -} - -.oi[data-glyph=badge]:before { - content: '\e016' -} - -.oi[data-glyph=ban]:before { - content: '\e017' -} - -.oi[data-glyph=bar-chart]:before { - content: '\e018' -} - -.oi[data-glyph=basket]:before { - content: '\e019' -} - -.oi[data-glyph=battery-empty]:before { - content: '\e01a' -} - -.oi[data-glyph=battery-full]:before { - content: '\e01b' -} - -.oi[data-glyph=beaker]:before { - content: '\e01c' -} - -.oi[data-glyph=bell]:before { - content: '\e01d' -} - -.oi[data-glyph=bluetooth]:before { - content: '\e01e' -} - -.oi[data-glyph=bold]:before { - content: '\e01f' -} - -.oi[data-glyph=bolt]:before { - content: '\e020' -} - -.oi[data-glyph=book]:before { - content: '\e021' -} - -.oi[data-glyph=bookmark]:before { - content: '\e022' -} - -.oi[data-glyph=box]:before { - content: '\e023' -} - -.oi[data-glyph=briefcase]:before { - content: '\e024' -} - -.oi[data-glyph=british-pound]:before { - content: '\e025' -} - -.oi[data-glyph=browser]:before { - content: '\e026' -} - -.oi[data-glyph=brush]:before { - content: '\e027' -} - -.oi[data-glyph=bug]:before { - content: '\e028' -} - -.oi[data-glyph=bullhorn]:before { - content: '\e029' -} - -.oi[data-glyph=calculator]:before { - content: '\e02a' -} - -.oi[data-glyph=calendar]:before { - content: '\e02b' -} - -.oi[data-glyph=camera-slr]:before { - content: '\e02c' -} - -.oi[data-glyph=caret-bottom]:before { - content: '\e02d' -} - -.oi[data-glyph=caret-left]:before { - content: '\e02e' -} - -.oi[data-glyph=caret-right]:before { - content: '\e02f' -} - -.oi[data-glyph=caret-top]:before { - content: '\e030' -} - -.oi[data-glyph=cart]:before { - content: '\e031' -} - -.oi[data-glyph=chat]:before { - content: '\e032' -} - -.oi[data-glyph=check]:before { - content: '\e033' -} - -.oi[data-glyph=chevron-bottom]:before { - content: '\e034' -} - -.oi[data-glyph=chevron-left]:before { - content: '\e035' -} - -.oi[data-glyph=chevron-right]:before { - content: '\e036' -} - -.oi[data-glyph=chevron-top]:before { - content: '\e037' -} - -.oi[data-glyph=circle-check]:before { - content: '\e038' -} - -.oi[data-glyph=circle-x]:before { - content: '\e039' -} - -.oi[data-glyph=clipboard]:before { - content: '\e03a' -} - -.oi[data-glyph=clock]:before { - content: '\e03b' -} - -.oi[data-glyph=cloud-download]:before { - content: '\e03c' -} - -.oi[data-glyph=cloud-upload]:before { - content: '\e03d' -} - -.oi[data-glyph=cloud]:before { - content: '\e03e' -} - -.oi[data-glyph=cloudy]:before { - content: '\e03f' -} - -.oi[data-glyph=code]:before { - content: '\e040' -} - -.oi[data-glyph=cog]:before { - content: '\e041' -} - -.oi[data-glyph=collapse-down]:before { - content: '\e042' -} - -.oi[data-glyph=collapse-left]:before { - content: '\e043' -} - -.oi[data-glyph=collapse-right]:before { - content: '\e044' -} - -.oi[data-glyph=collapse-up]:before { - content: '\e045' -} - -.oi[data-glyph=command]:before { - content: '\e046' -} - -.oi[data-glyph=comment-square]:before { - content: '\e047' -} - -.oi[data-glyph=compass]:before { - content: '\e048' -} - -.oi[data-glyph=contrast]:before { - content: '\e049' -} - -.oi[data-glyph=copywriting]:before { - content: '\e04a' -} - -.oi[data-glyph=credit-card]:before { - content: '\e04b' -} - -.oi[data-glyph=crop]:before { - content: '\e04c' -} - -.oi[data-glyph=dashboard]:before { - content: '\e04d' -} - -.oi[data-glyph=data-transfer-download]:before { - content: '\e04e' -} - -.oi[data-glyph=data-transfer-upload]:before { - content: '\e04f' -} - -.oi[data-glyph=delete]:before { - content: '\e050' -} - -.oi[data-glyph=dial]:before { - content: '\e051' -} - -.oi[data-glyph=document]:before { - content: '\e052' -} - -.oi[data-glyph=dollar]:before { - content: '\e053' -} - -.oi[data-glyph=double-quote-sans-left]:before { - content: '\e054' -} - -.oi[data-glyph=double-quote-sans-right]:before { - content: '\e055' -} - -.oi[data-glyph=double-quote-serif-left]:before { - content: '\e056' -} - -.oi[data-glyph=double-quote-serif-right]:before { - content: '\e057' -} - -.oi[data-glyph=droplet]:before { - content: '\e058' -} - -.oi[data-glyph=eject]:before { - content: '\e059' -} - -.oi[data-glyph=elevator]:before { - content: '\e05a' -} - -.oi[data-glyph=ellipses]:before { - content: '\e05b' -} - -.oi[data-glyph=envelope-closed]:before { - content: '\e05c' -} - -.oi[data-glyph=envelope-open]:before { - content: '\e05d' -} - -.oi[data-glyph=euro]:before { - content: '\e05e' -} - -.oi[data-glyph=excerpt]:before { - content: '\e05f' -} - -.oi[data-glyph=expand-down]:before { - content: '\e060' -} - -.oi[data-glyph=expand-left]:before { - content: '\e061' -} - -.oi[data-glyph=expand-right]:before { - content: '\e062' -} - -.oi[data-glyph=expand-up]:before { - content: '\e063' -} - -.oi[data-glyph=external-link]:before { - content: '\e064' -} - -.oi[data-glyph=eye]:before { - content: '\e065' -} - -.oi[data-glyph=eyedropper]:before { - content: '\e066' -} - -.oi[data-glyph=file]:before { - content: '\e067' -} - -.oi[data-glyph=fire]:before { - content: '\e068' -} - -.oi[data-glyph=flag]:before { - content: '\e069' -} - -.oi[data-glyph=flash]:before { - content: '\e06a' -} - -.oi[data-glyph=folder]:before { - content: '\e06b' -} - -.oi[data-glyph=fork]:before { - content: '\e06c' -} - -.oi[data-glyph=fullscreen-enter]:before { - content: '\e06d' -} - -.oi[data-glyph=fullscreen-exit]:before { - content: '\e06e' -} - -.oi[data-glyph=globe]:before { - content: '\e06f' -} - -.oi[data-glyph=graph]:before { - content: '\e070' -} - -.oi[data-glyph=grid-four-up]:before { - content: '\e071' -} - -.oi[data-glyph=grid-three-up]:before { - content: '\e072' -} - -.oi[data-glyph=grid-two-up]:before { - content: '\e073' -} - -.oi[data-glyph=hard-drive]:before { - content: '\e074' -} - -.oi[data-glyph=header]:before { - content: '\e075' -} - -.oi[data-glyph=headphones]:before { - content: '\e076' -} - -.oi[data-glyph=heart]:before { - content: '\e077' -} - -.oi[data-glyph=home]:before { - content: '\e078' -} - -.oi[data-glyph=image]:before { - content: '\e079' -} - -.oi[data-glyph=inbox]:before { - content: '\e07a' -} - -.oi[data-glyph=infinity]:before { - content: '\e07b' -} - -.oi[data-glyph=info]:before { - content: '\e07c' -} - -.oi[data-glyph=italic]:before { - content: '\e07d' -} - -.oi[data-glyph=justify-center]:before { - content: '\e07e' -} - -.oi[data-glyph=justify-left]:before { - content: '\e07f' -} - -.oi[data-glyph=justify-right]:before { - content: '\e080' -} - -.oi[data-glyph=key]:before { - content: '\e081' -} - -.oi[data-glyph=laptop]:before { - content: '\e082' -} - -.oi[data-glyph=layers]:before { - content: '\e083' -} - -.oi[data-glyph=lightbulb]:before { - content: '\e084' -} - -.oi[data-glyph=link-broken]:before { - content: '\e085' -} - -.oi[data-glyph=link-intact]:before { - content: '\e086' -} - -.oi[data-glyph=list-rich]:before { - content: '\e087' -} - -.oi[data-glyph=list]:before { - content: '\e088' -} - -.oi[data-glyph=location]:before { - content: '\e089' -} - -.oi[data-glyph=lock-locked]:before { - content: '\e08a' -} - -.oi[data-glyph=lock-unlocked]:before { - content: '\e08b' -} - -.oi[data-glyph=loop-circular]:before { - content: '\e08c' -} - -.oi[data-glyph=loop-square]:before { - content: '\e08d' -} - -.oi[data-glyph=loop]:before { - content: '\e08e' -} - -.oi[data-glyph=magnifying-glass]:before { - content: '\e08f' -} - -.oi[data-glyph=map-marker]:before { - content: '\e090' -} - -.oi[data-glyph=map]:before { - content: '\e091' -} - -.oi[data-glyph=media-pause]:before { - content: '\e092' -} - -.oi[data-glyph=media-play]:before { - content: '\e093' -} - -.oi[data-glyph=media-record]:before { - content: '\e094' -} - -.oi[data-glyph=media-skip-backward]:before { - content: '\e095' -} - -.oi[data-glyph=media-skip-forward]:before { - content: '\e096' -} - -.oi[data-glyph=media-step-backward]:before { - content: '\e097' -} - -.oi[data-glyph=media-step-forward]:before { - content: '\e098' -} - -.oi[data-glyph=media-stop]:before { - content: '\e099' -} - -.oi[data-glyph=medical-cross]:before { - content: '\e09a' -} - -.oi[data-glyph=menu]:before { - content: '\e09b' -} - -.oi[data-glyph=microphone]:before { - content: '\e09c' -} - -.oi[data-glyph=minus]:before { - content: '\e09d' -} - -.oi[data-glyph=monitor]:before { - content: '\e09e' -} - -.oi[data-glyph=moon]:before { - content: '\e09f' -} - -.oi[data-glyph=move]:before { - content: '\e0a0' -} - -.oi[data-glyph=musical-note]:before { - content: '\e0a1' -} - -.oi[data-glyph=paperclip]:before { - content: '\e0a2' -} - -.oi[data-glyph=pencil]:before { - content: '\e0a3' -} - -.oi[data-glyph=people]:before { - content: '\e0a4' -} - -.oi[data-glyph=person]:before { - content: '\e0a5' -} - -.oi[data-glyph=phone]:before { - content: '\e0a6' -} - -.oi[data-glyph=pie-chart]:before { - content: '\e0a7' -} - -.oi[data-glyph=pin]:before { - content: '\e0a8' -} - -.oi[data-glyph=play-circle]:before { - content: '\e0a9' -} - -.oi[data-glyph=plus]:before { - content: '\e0aa' -} - -.oi[data-glyph=power-standby]:before { - content: '\e0ab' -} - -.oi[data-glyph=print]:before { - content: '\e0ac' -} - -.oi[data-glyph=project]:before { - content: '\e0ad' -} - -.oi[data-glyph=pulse]:before { - content: '\e0ae' -} - -.oi[data-glyph=puzzle-piece]:before { - content: '\e0af' -} - -.oi[data-glyph=question-mark]:before { - content: '\e0b0' -} - -.oi[data-glyph=rain]:before { - content: '\e0b1' -} - -.oi[data-glyph=random]:before { - content: '\e0b2' -} - -.oi[data-glyph=reload]:before { - content: '\e0b3' -} - -.oi[data-glyph=resize-both]:before { - content: '\e0b4' -} - -.oi[data-glyph=resize-height]:before { - content: '\e0b5' -} - -.oi[data-glyph=resize-width]:before { - content: '\e0b6' -} - -.oi[data-glyph=rss-alt]:before { - content: '\e0b7' -} - -.oi[data-glyph=rss]:before { - content: '\e0b8' -} - -.oi[data-glyph=script]:before { - content: '\e0b9' -} - -.oi[data-glyph=share-boxed]:before { - content: '\e0ba' -} - -.oi[data-glyph=share]:before { - content: '\e0bb' -} - -.oi[data-glyph=shield]:before { - content: '\e0bc' -} - -.oi[data-glyph=signal]:before { - content: '\e0bd' -} - -.oi[data-glyph=signpost]:before { - content: '\e0be' -} - -.oi[data-glyph=sort-ascending]:before { - content: '\e0bf' -} - -.oi[data-glyph=sort-descending]:before { - content: '\e0c0' -} - -.oi[data-glyph=spreadsheet]:before { - content: '\e0c1' -} - -.oi[data-glyph=star]:before { - content: '\e0c2' -} - -.oi[data-glyph=sun]:before { - content: '\e0c3' -} - -.oi[data-glyph=tablet]:before { - content: '\e0c4' -} - -.oi[data-glyph=tag]:before { - content: '\e0c5' -} - -.oi[data-glyph=tags]:before { - content: '\e0c6' -} - -.oi[data-glyph=target]:before { - content: '\e0c7' -} - -.oi[data-glyph=task]:before { - content: '\e0c8' -} - -.oi[data-glyph=terminal]:before { - content: '\e0c9' -} - -.oi[data-glyph=text]:before { - content: '\e0ca' -} - -.oi[data-glyph=thumb-down]:before { - content: '\e0cb' -} - -.oi[data-glyph=thumb-up]:before { - content: '\e0cc' -} - -.oi[data-glyph=timer]:before { - content: '\e0cd' -} - -.oi[data-glyph=transfer]:before { - content: '\e0ce' -} - -.oi[data-glyph=trash]:before { - content: '\e0cf' -} - -.oi[data-glyph=underline]:before { - content: '\e0d0' -} - -.oi[data-glyph=vertical-align-bottom]:before { - content: '\e0d1' -} - -.oi[data-glyph=vertical-align-center]:before { - content: '\e0d2' -} - -.oi[data-glyph=vertical-align-top]:before { - content: '\e0d3' -} - -.oi[data-glyph=video]:before { - content: '\e0d4' -} - -.oi[data-glyph=volume-high]:before { - content: '\e0d5' -} - -.oi[data-glyph=volume-low]:before { - content: '\e0d6' -} - -.oi[data-glyph=volume-off]:before { - content: '\e0d7' -} - -.oi[data-glyph=warning]:before { - content: '\e0d8' -} - -.oi[data-glyph=wifi]:before { - content: '\e0d9' -} - -.oi[data-glyph=wrench]:before { - content: '\e0da' -} - -.oi[data-glyph=x]:before { - content: '\e0db' -} - -.oi[data-glyph=yen]:before { - content: '\e0dc' -} - -.oi[data-glyph=zoom-in]:before { - content: '\e0dd' -} - -.oi[data-glyph=zoom-out]:before { - content: '\e0de' -} \ No newline at end of file diff --git a/js/src/clients.js b/js/src/clients.js index cfc9ddf..ae681f5 100644 --- a/js/src/clients.js +++ b/js/src/clients.js @@ -101,7 +101,7 @@ require('../../css/style.css'); var baseUrl = OC.generateUrl('/apps/timetracker/ajax/clients'); var editIcon = function(cell, formatterParams){ //plain text value - return ""; + return ""; }; diff --git a/js/src/goals.js b/js/src/goals.js index 8c6d210..cc9d196 100644 --- a/js/src/goals.js +++ b/js/src/goals.js @@ -95,7 +95,7 @@ require('../../css/style.css'); var baseUrl = OC.generateUrl('/apps/timetracker/ajax/goals'); var editIcon = function(cell, formatterParams){ //plain text value - return ""; + return ""; }; diff --git a/js/src/kingtable.js b/js/src/kingtable.js deleted file mode 100644 index 811b198..0000000 --- a/js/src/kingtable.js +++ /dev/null @@ -1,15 +0,0 @@ -/** - * KingTable 2.0.0 - * https://github.com/RobertoPrevato/KingTable - * - * Copyright 2018, Roberto Prevato - * https://robertoprevato.github.io - * - * Licensed under the MIT license: - * http://www.opensource.org/licenses/MIT - */ -!function e(t,n,r){function i(s,o){if(!n[s]){if(!t[s]){var u="function"==typeof require&&require;if(!o&&u)return u(s,!0);if(a)return a(s,!0);var l=new Error("Cannot find module '"+s+"'");throw l.code="MODULE_NOT_FOUND",l}var f=n[s]={exports:{}};t[s][0].call(f.exports,function(e){var n=t[s][1][e];return i(n||e)},f,f.exports,e,t,n,r)}return n[s].exports}for(var a="function"==typeof require&&require,s=0;s6)return!1;return a(t[0])}return!1}Object.defineProperty(n,"__esModule",{value:!0});var o=e("../../scripts/utils"),u=r(o),l=e("../../scripts/components/string"),f=r(l),c=e("../../scripts/components/regex"),d=r(c),p=e("../../scripts/components/reflection"),h=r(p),m=e("../../scripts/exceptions"),g={autoParseNumbers:!0,ci:!0};n.default={normalizeOrder:i,lookSortableAsNumber:s,options:g,parseSortBy:function(e){if(e){var t=e.split(/\s*,\s*/g);return u.default.map(t,function(e){var t=e.split(/\s/),n=t[0],r=t[1]||"asc";return[n,f.default.startsWith(r,"asc",!0)?1:-1]})}},humanSortBy:function(e,t){return e&&e.length?u.default.map(e,function(e){var n=e[0];return 1===e[1]?t?n+" asc":n:n+" desc"}).join(", "):""},getSortCriteria:function(e){var t,n=this,r=e.length;if(1==e.length){var i=e[0];if(u.default.isString(i)&&i.search(/,|\s/)>-1)return this.parseSortBy(i)}if(r>1){var a=u.default.toArray(e);t=u.default.map(a,function(e){return n.normalizeSortByValue(e,!0)})}else t=this.normalizeSortByValue(e[0]);return t},normalizeSortByValue:function(e,t){var n=this;if(u.default.isString(e))return t?[e,"asc"]:[[e,"asc"]];if(u.default.isArray(e))return u.default.isArray(e[0])?e:u.default.map(e,function(e){return n.normalizeSortByValue(e,!0)});if(u.default.isPlainObject(e)){var r,i=[];for(r in e)i.push([r,e[r]]);return i}(0,m.TypeException)("sort","string | [] | {}")},compareStrings:function(e,t,n){if(this.options.autoParseNumbers){var r=s(e),i=s(t);if(!1!==r||!1!==i){if(r===i)return 0;if(!1!==r&&!1===t)return n;if(!1===r&&!1!==t)return-n;if(ri)return n}}return f.default.compare(e,t,n,this.options)},sortBy:function(e){u.default.isArray(e)||(0,m.TypeException)("ar","array");var t=arguments.length,n=u.default.toArray(arguments).slice(1,t),r=this.getSortCriteria(n);r=i(r);var a=r.length,s=u.default.isString,o=this.compareStrings.bind(this),l=void 0,f=null;return e.sort(function(e,t){if(e===t)return 0;if(e!==l&&t===l)return-1;if(e===l&&t!==l)return 1;if(e!==f&&t===f)return-1;if(e===f&&t!==f)return 1;for(var n=0;np)return c}}return 0}),e},sortByProperty:function(e,t,n){u.default.isArray(e)||(0,m.TypeException)("arr","array"),u.default.isString(t)||(0,m.TypeException)("property","string"),u.default.isUnd(n)||(n="asc"),n=u.default.isNumber(n)?n:/^asc/i.test(n)?1:-1;var r={};return r[t]=n,this.sortBy(e,r)},searchByStringProperty:function(e){return u.default.require(e,["pattern","collection","property"]),this.searchByStringProperties(u.default.extend(e,{properties:[e.property]}))},search:function(e){if(!e||!e.length)return e;var t=arguments.length;if(t<2)return e;for(var n,r,i=u.default.toArray(arguments).slice(1,t),a=[],s=u.default.isString,o=0,t=e.length;ot[R])return-M;if(e[R]f)return M;if(i[L][I](l)o[L][I](f))return M;var c=e[y],d=t[y];if(c[N](i[H])&&d[N](o[H])){if(c[i[H]][D]()[F]()d[o[H]][D]()[F]())return M}if(i[A]>o[A])return-M;if(i[A]t.length;)n=n.substr(1,n.length);return n}},month:{rx:/M{1,4}/,fn:function(e,t,n,i){var a=(e.getMonth()+1).toString();switch(t.length){case 1:return a;case 2:return r(a,2);case 3:return a=e.getMonth(),i.monthShort[a];case 4:return a=e.getMonth(),i.month[a]}}},day:{rx:/D{1,4}/,fn:function(e,t,n,i){var a=e.getDate().toString();switch(t.length){case 1:return a;case 2:return r(a.toString(),2);case 3:return a=e.getDay(),i.weekShort[a];case 4:return a=e.getDay(),i.week[a]}}},hour:{rx:/h{1,2}/i,fn:function(e,t,n){var r=e.getHours(),i=/t{1,2}/i.test(n);for(i&&r>12&&(r%=12),r=r.toString();r.lengthn?r.substr(0,n):r}},hoursoffset:{rx:/z{1,3}/i,fn:function(e,t,n){var i=-e.getTimezoneOffset()/60,a=i>0?"+":"";switch(t.length){case 1:return a+i;case 2:return a+r(i,2);case 3:return a+r(i,2)+":00"}}},ampm:{rx:/t{1,2}/i,fn:function(e,t){var n,r=e.getHours(),i=/T{1,2}/.test(t);switch(t.length){case 1:n=r>12?"p":"a";break;case 2:n=r>12?"pm":"am"}return i?n.toUpperCase():n}},weekday:{rx:/w{1,2}/i,fn:function(e,t,n,r){var i=e.getDay(),a=t.length>1?"week":"weekShort",s=r[a];return s&&void 0!==s[i]?s[i]:i}}},u=/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z?$|^\d{4}-\d{2}-\d{2}[T\s]\d{2}:\d{2}:\d{2}(?:\sUTC)?$/,l=/^(\d{4})\D(\d{1,2})\D(\d{1,2})(?:\s(\d{1,2})(?:\D(\d{1,2}))?(?:\D(\d{1,2}))?)?$/;n.default={looksLikeDate:function(e){return!!e&&(e instanceof Date||"string"==typeof e&&(!!l.exec(e)||!!u.exec(e)))},defaults:{format:{short:"DD.MM.YYYY",long:"DD.MM.YYYY HH:mm:ss"},week:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],weekShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],month:["January","February","March","April","May","June","July","August","September","October","November","December"],monthShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]},parse:function(e){a.default.isString(e)||(0,s.TypeException)("s","string");var t=l.exec(e);if(t){var n=t[4];if(n){return new Date(parseInt(t[1]),parseInt(t[2])-1,parseInt(t[3]),parseInt(n),parseInt(t[5]||0),parseInt(t[6]||0))}return new Date(t[1],t[2]-1,t[3])}if(u.exec(e))return/Z$/.test(e)||-1!=e.indexOf("UTC")||(e+="Z"),new Date(e)},format:function(e,t,n){t||(t=this.defaults.format.short),n||(n=this.defaults);var r=t;for(var i in o){var a=o[i],s=t.match(a.rx);s&&(r=r.replace(a.rx,a.fn(e,s[0],t,n)))}return r},formatWithTime:function(e,t){return this.format(e,this.defaults.format.long,t)},isValid:function(e){return e instanceof Date&&isFinite(e)},sameDay:function(e,t){return e.getFullYear()===t.getFullYear()&&e.getMonth()===t.getMonth()&&e.getDate()===t.getDate()},isToday:function(e){return this.sameDay(e,new Date)},hasTime:function(e){var t=e.getHours(),n=e.getMinutes(),r=e.getSeconds();return!!(t||n||r)},toIso8601:function(e){return this.format(e,"YYYY-MM-DD")+"T"+this.format(e,"hh:mm:ss")+"."+this.format(e,"fff")+"Z"},toExcelDateValue:function(e){return(25569+(e.getTime()-60*e.getTimezoneOffset()*1e3)/864e5).toString().substr(0,5)}}},{"../../scripts/exceptions":20,"../../scripts/utils.js":34}],3:[function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var i=function(){function e(e,t){for(var n=0;na));s++)e=this.replaceAt(e,i.i-n,i.v);return e},snakeCase:function(e){return e?this.removeMultipleSpaces(e.trim())[c](/[^a-zA-Z0-9]/g,"_")[c](/([a-z])[\s\-]?([A-Z])/g,function(e,t,n){return t+"_"+i(n)})[c](/([A-Z]+)/g,function(e,t){return i(t)})[c](/_{2,}/g,"_"):e},kebabCase:function(e){return e?this.removeMultipleSpaces(e.trim())[c](/[^a-zA-Z0-9]/g,"-")[c](/([a-z])[\s\-]?([A-Z])/g,function(e,t,n){return t+"-"+i(n)})[c](/([A-Z]+)/g,function(e,t){return i(t)})[c](/-{2,}/g,"-"):""},camelCase:function(e){return e?this.removeMultipleSpaces(e.trim())[c](/[^a-zA-Z0-9]+([a-zA-Z])?/g,function(e,t){return a(t)})[c](/([a-z])[\s\-]?([A-Z])/g,function(e,t,n){return t+a(n)})[c](/^([A-Z]+)/g,function(e,t){return i(t)}):e},format:function(e){var t=Array.prototype.slice.call(arguments,1);return e[c](/{(\d+)}/g,function(e,n){return void 0!==t[n]?t[n]:e})},getString:function(e){return"string"==typeof e?e:e.toString?e.toString():""},compare:function(e,t,n,r){n=u.default.isNumber(n)?n:/^asc/i.test(n)?1:-1;var i=u.default.extend({ci:!0},r);return e&&!t?n:!e&&t?-n:e||t?e==t?0:(u.default.isString(e)||(e=e.toString()),u.default.isString(t)||(t=t.toString()),i.ci&&(e=e.toLowerCase(),t=t.toLowerCase()),(0,f.default)(e)<(0,f.default)(t)?-n:n):0},ofLength:function(e,t){return new Array(t+1).join(e)},center:function(e,t,n){if(t<=0)throw new Error("length must be > 0");if(n||(n=" "),!e)return this.ofLength(n,t);if(1!=n.length)throw new Error(d);for(var r=Math.floor((t-e.length)/2),i=this.ofLength(n,r),a=!1,s=i+e+i;s.length 0");if(n||(n=" "),!e)return this.ofLength(n,t);if(1!=n.length)throw new Error(d);for(;e.length 0");if(n||(n=" "),!e)return this.ofLength(n,t);if(1!=n.length)throw new Error(d);for(;e.length-1&&e!=l?l:e}Object.defineProperty(n,"__esModule",{value:!0});var a=e("../../scripts/utils"),s=r(a),o=e("../../scripts/data/json"),u=r(o),l="application/json",f={type:"POST",headers:{"X-Requested-With":"XMLHttpRequest","Content-Type":l},json:{parseDates:!0}};n.default={defaults:f,requestBeforeSend:function(e,t,n){},setup:function(e){if(!s.default.isPlainObject(e))throw new Error("Invalid options for AJAX setup.");return s.default.extend(this.defaults,e),this},converters:{"application/json":function(e,t,n){return u.default.parse(e,n.json)}},createQs:function(e){if(!e)return"";var t,n,r=[];for(t in e)n=e[t],s.default.isNullOrEmptyString(n)||r.push([t,n]);return r.sort(function(e,t){return e>t?1:e-1))throw"application/x-www-form-urlencoded; charset=UTF-8"==g?"Not implemented":"invalid or not implemented content type: "+g;m=u.default.compose(m),r.requestBeforeSend(d,t,e),d.send(m)}else r.requestBeforeSend(d,t,e),d.send()})},get:function(e,t){return t=t||{},t.url=e,t.type="GET",this.shot(t)},post:function(e,t){return t=t||{},t.url=e,t.type="POST",this.shot(t)}}},{"../../scripts/data/json":13,"../../scripts/utils":34}],10:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../scripts/utils"),i=function(e){return e&&e.__esModule?e:{default:e}}(r),a={allStrings:1,keepType:2};n.default={default:{addBom:!0,separator:",",addSeparatorLine:!1,typeHandling:a.keepType},serialize:function(e,t){for(var n=i.default.extend({},this.default,t),r=[],s=n.separator,o=n.typeHandling,u=n.addBom?"\ufeff":"",l=0,f=e.length;l-1)&&(m='"'+m+'"'),c.push(m)}r.push(c.join(s))}return n.addSeparatorLine&&r.push("\t"+s),u+r.join("\n")}}},{"../../scripts/utils":34}],11:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default={supportsCsExport:function(){return navigator.msSaveBlob||function(){return void 0!==document.createElement("a").download}()},exportfile:function(e,t,n){var r=new Blob([t],{type:n});if(navigator.msSaveBlob)navigator.msSaveBlob(r,e);else{var i=document.createElement("a");if(void 0!==i.download){var a=URL.createObjectURL(r);i.setAttribute("href",a),i.setAttribute("download",e);var s={visibility:"hidden",position:"absolute",left:"-9999px"};for(var o in s)i.style[o]=s[o];document.body.appendChild(i),i.click(),document.body.removeChild(i)}}}}},{}],12:[function(e,t,n){"use strict";function r(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}function a(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function s(e){return"number"==typeof e}function o(e){return e.replace(/&/g,"&").replace(//g,">").replace(/"/g,""").replace(/'/g,"'")}Object.defineProperty(n,"__esModule",{value:!0});var u=function(){function e(e,t){for(var n=0;n0?new Array(e*n+1).join(t||" "):"",f="<"+o;for(r in u)void 0!==u[r]&&(c.indexOf(r)>-1?f+=" "+r:f+=" "+r+'="'+u[r]+'"');if(a)return f+=" />",e>0&&(f=l+f+"\n"),f;f+=">";var d=i.children;e>0&&d.length&&(f+="\n");for(var p=0,h=d.length;p":f+="",e>0&&(f=l+f+"\n"),f}},{key:"tagName",get:function(){return this._tagName},set:function(e){if("string"!=typeof e)throw new Error("tagName must be a string");if(!e.trim())throw new Error("tagName must have a length");if(e.indexOf(" ")>-1)throw new Error("tagName cannot contain spaces");this._tagName=e}}]),e}(),f="area base basefont br col frame hr img input isindex link meta param".split(" "),c="checked selected disabled readonly multiple ismap isMap defer noresize noResize nowrap noWrap noshade noShade compact".split(" "),d=function(e){function t(e,n,i){a(this,t);var s=r(this,(t.__proto__||Object.getPrototypeOf(t)).call(this,e,n,i));return s.empty=f.indexOf(e.toLowerCase())>-1,s}return i(t,e),u(t,[{key:"id",get:function(){return this.attributes.id},set:function(e){this.attributes.id=e}}]),t}(l),p=function(){function e(t){a(this,e),this.text=t}return u(e,[{key:"toString",value:function(e,t,n){var e=s(e)?e:0,n=s(n)?n:0,r=e>0?new Array(e*n+1).join(t||" "):"";return r+this.text+(r?"\n":"")}},{key:"text",get:function(){return this._text},set:function(e){e||(e=""),"string"!=typeof e&&(e=e.toString()),this._text=o(e)}}]),e}(),h=function(){function e(t){a(this,e),this.html=t}return u(e,[{key:"toString",value:function(e,t,n){var e=s(e)?e:0,n=s(n)?n:0,r=e>0?new Array(e*n+1).join(t||" "):"";return r+this.html+(r?"\n":"")}}]),e}(),m=function(){function e(t){a(this,e),this.text=t}return u(e,[{key:"toString",value:function(e,t,n){var e=s(e)?e:0,n=s(n)?n:0,r=e>0?new Array(e*n+1).join(t||" "):"";return r+"\x3c!--"+this.text+"--\x3e"+(r?"\n":"")}},{key:"text",get:function(){return this._text},set:function(e){e||(e=""),"string"!=typeof e&&(e=e.toString()),e=e.replace(//g,""),this._text=e}}]),e}(),g=function(){function e(t){a(this,e),this.children=t,this.hidden=!1}return u(e,[{key:"toString",value:function(e,t,n){var r="",i=this.children;if(!i||this.hidden)return r;for(var a=0,s=i.length;a0&&(new Date).getTime()>m?c.push(p):t(h)&&(f=r?p:h)}}return c.length&&this.remove(e,function(e){return c.indexOf(e)>-1}),f}},remove:function(e,t,n){var r=i(n);if(!t)return void r.removeItem(e);var a,s=r.getItem(e);if(s){try{s=u.default.parse(s)}catch(t){return void r.removeItem(e)}var o=s.length,l=[];for(a=0;a0?l+r:-1,c={ts:l,expiration:f,data:t},d=o.getItem(e);if(d){try{d=u.default.parse(d)}catch(r){return o.removeItem(e),this.set(e,t,n)}d.length>=n&&d.shift(),d.push(c)}else d=[{ts:l,expiration:f,data:t}];return o.setItem(e,u.default.compose(d))}}},{"../../scripts/data/json":13,"../../scripts/exceptions":20,"../../scripts/utils":34}],15:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r={};n.default={items:function(){return r},length:function(){var e,t=0;for(e in r)t++;return t},getItem:function(e){return r[e]},setItem:function(e,t){r[e]=t},removeItem:function(e){delete r[e]},clear:function(){var e;for(e in r)delete r[e]}}},{}],16:[function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0});var i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},a=function(){function e(e,t){for(var n=0;n/g,">").replace(/"/g,""").replace(/'/g,"'")}},{key:"escape",value:function(e){return e?this.escapeHtml(e):""}}]),e}();n.default=o},{"../../scripts/utils":34}],18:[function(e,t,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=e("../../scripts/utils");!function(e){e&&e.__esModule}(r);n.default={normal:function(e){return''+e.replace(/\sxmlns="http:\/\/www\.w3\.org\/\d+\/xhtml"/,"")},pretty:function(e,t){e=this.normal(e),"number"!=typeof t&&(t=2);var n=/(>)(<)(\/*)/g,r=[];e=e.replace(n,"$1\r\n$2$3");for(var i=0,a=e.split("\r\n"),s=a.length,o=0;o]*>$/)?l=0:u.match(/^<\/\w/)?0!=i&&(i-=1):l=u.match(/^<\w[^>]*[^\/]>.*$/)?1:0;var f=new Array(i*t).join(" ");r.push(f+u+"\r\n"),i+=l}return r.join("")}}},{"../../scripts/utils":34}],19:[function(e,t,n){"use strict";function r(e,t,n){if(t.search(/\s/)>-1){t=t.split(/\s/g);for(var i=0,a=t[F];i-1){e.substr(0,t);return[e.substr(0,t),e.substr(t+1)]}return[e,""]}Object.defineProperty(n,"__esModule",{value:!0});var C="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},O=e("../scripts/utils.js"),V=function(e){return e&&e.__esModule?e:{default:e}}(O),j="object",M="string",F="length",D=V.default.any,H=V.default.each,I=".",N=[];n.default={splitNamespace:_,empty:function(e){for(;e.hasChildNodes();)this.off(e.lastChild),e.removeChild(e.lastChild)},remove:function(e){if(e){this.off(e);var t=e.parentElement||e.parentNode;t&&t.removeChild(e)}},closest:function(e,t,n){if(e&&t){if(!n&&t(e))return e;for(var r=e;r=r.parentElement;)if(t(r))return r}},closestWithTag:function(e,t,n){if(t)return t=t.toUpperCase(),this.closest(e,function(e){return e.tagName==t},n)},closestWithClass:function(e,t,n){if(t)return this.closest(e,function(e){return s(e,t)},n)},contains:function(e,t){if(!e||!t)return!1;if(!e.hasChildNodes())return!1;for(var n=e.childNodes,r=n.length,i=0;i="+t),r(n)&&(i=" <="+n)):i=" to be positive.",new Error(i)}Object.defineProperty(n,"__esModule",{value:!0});var l="???";n.ArgumentException=a,n.ArgumentNullException=i,n.TypeException=s,n.OutOfRangeException=u,n.OperationException=o},{}],21:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(n,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;nt.totalPageCount||e===t.page)}},{key:"onPageChange",value:function(){}},{key:"getPageCount",value:function(e,t){return i(e,t),e===1/0?1/0:e===-1/0?0:e<1?0:e>t?e%t==0?e/t:Math.ceil(e/t):1}},{key:"dispose",value:function(){delete this.onPageChange}},{key:"resultsPerPage",get:function(){return this._resultsPerPage},set:function(e){e||(e=0),i(e);var t=this,n=t.totalItemsCount;if(n){var r=t.getPageCount(n,e);t.totalPageCount=r,r<=t._page&&(t.page=r)}t._resultsPerPage=e,t.updateItemsNumber()}},{key:"page",get:function(){return this._page},set:function(e){i(e),e!=this.page&&(this._page=e,this.updateItemsNumber(),this.onPageChange())}}]),e}();n.default=l},{"../../scripts/utils":34}],23:[function(e,t,n){"use strict";function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(n,"__esModule",{value:!0}),n.TextSlider=void 0;var i=function(){function e(e,t){for(var n=0;n'+(0,d.escapeHtml)(u)+""}return f"+i+""}})}return r}},{key:"getFields",value:function(){var e=this.table,t=h.default.clone(e.columns),n=this.options,r=n.itemCount,i=this.getGeneratedFields(),a=r?{name:"ε_row",displayName:"#"}:null;a&&t.unshift(a);var s=n.fields;return s?(h.default.isFunction(s)&&(s=s.call(this,t)),t=i.concat(s.concat(t))):t=i.concat(t),t}},{key:"build",value:function(){var e=this,t=e.table,n=t.getData({format:!0,hide:!1});if(!n||!n.length)return e.display(e.emptyView());var r=e.getFields(),i=e.buildCaption(),a=e.buildView(r,n),s=e.buildRoot(i,a);e.display(s)}},{key:"buildRoot",value:function(e,t){var n=this.table,r={class:"king-table-region"};return n.id&&(r.id=n.id),new u.VHtmlElement("div",r,[e,t])}},{key:"buildView",value:function(e,t){this.table;return new u.VHtmlElement("table",{class:"king-table"},[this.buildHead(e),this.buildBody(e,t)])}},{key:"buildHead",value:function(e){var t=(this.table,new u.VHtmlElement("tr",{},h.default.map(h.default.values(e),function(e){if(!e.hidden&&!e.secret)return new u.VHtmlElement("th",{class:e.css},new u.VTextElement(e.displayName))})));return new u.VHtmlElement("thead",{class:"king-table-head"},t)}},{key:"buildBody",value:function(e,t){var n=this,r=this.table,i=r.builder,a=r.options.formattedSuffix,s=r.searchText?r.filters.getRuleByKey("search").value:null,o=r.options.autoHighlightSearchProperties,l=-1,f=h.default.map(t,function(t){l+=1,t.__ix__=l;for(var r,f,c=[],p=0,m=e.length;p0&&(c+=" "+n.of+" "+i),f(a)&&f(s)&&s>0&&(c+=" - "+n.results+" "+a+" - "+s,f(o)&&(c+=" "+n.of+" - "+o))),l&&e.options.showAnchorTimestamp&&(c+=" - "+n.anchorTime+" "+l),new u.VHtmlElement("span",{class:"pagination-info"},new u.VTextElement(c))}},{key:"emptyView",value:function(e){var t=this.getReg(),n=new u.VHtmlElement("div",{class:"king-table-empty"},new u.VHtmlElement("span",0,new u.VTextElement(t.noData)));return e?n:this.singleLine(this.table,n)}},{key:"errorView",value:function(e){return e||(e=this.getReg().errorFetchingData),this.singleLine(this.table,new u.VHtmlFragment('
\n \n '+e+'\n \n \n
'))}},{key:"loadingView",value:function(){var e=(this.table,this.getReg()),t=this.buildCaption();return t.children.push(new u.VHtmlElement("div",{class:"loading-info"},[new u.VHtmlElement("span",{class:"loading-text"},new u.VTextElement(e.loading)),new u.VHtmlElement("span",{class:"mini-loader"})])),this.buildRoot([t])}},{key:"display",value:function(e){var t=this.table;h.default.isString(e)||(e=e.toString());var n=t.element;if(n){for(n.classList.add("king-table"),t.emit("empty:element",n);n.hasChildNodes();)n.removeChild(n.lastChild);n.innerHTML=e}}},{key:"singleLine",value:function(e){var t=(this.table,this.buildCaption());return t.children.push(new u.VHtmlElement("br"),new u.VHtmlElement("div",{class:"loading-info"},h.default.isString(e)?new u.VTextElement(e):e)),this.buildRoot([t])}},{key:"loadingHandler",value:function(){var e=this,n=e.table;e.unsetLoadingHandler();var r=n.hasData()?t.options.loadInfoDelay:0;e.showLoadingTimeout=setTimeout(function(){if(!n.loading)return e.unsetLoadingHandler();e.display(e.loadingView())},r)}},{key:"unsetLoadingHandler",value:function(){return clearTimeout(this.showLoadingTimeout),this.showLoadingTimeout=null,this}},{key:"dispose", -value:function(){var e=this.table,t=e.element;t&&g.default.empty(t),this.stopListening(this.table),this.table=null,delete this.options}}],[{key:"options",get:function(){return{handleLoadingInfo:!0,loadInfoDelay:500,paginationInfo:!0}}}]),t}(f.default);n.default=v},{"../../scripts/data/html":12,"../../scripts/dom":19,"../../scripts/raise":26,"../../scripts/tables/kingtable.html.base.builder":28,"../../scripts/utils":34}],30:[function(e,t,n){"use strict";function r(e){return e&&e.__esModule?e:{default:e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function a(e,t){if(!e)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return!t||"object"!=typeof t&&"function"!=typeof t?e:t}function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(n,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;nn[r]?1:t[r]0?x.default.debounce(e,t,this):e,this}},{key:"getViewResolver",value:function(){var e=this.options,t=e.view,n=e.views;x.default.isString(t)||(0,w.default)(21,"Missing view configuration for Rich HTML builder");var r=x.default.find(n,function(e){return e.name==t});r||(0,w.default)(22,"Missing view resolver for view: "+t);var i=r.resolver;return!0===i?this:(i||(0,w.default)(33,"Missing resolver in view configuration '"+t+"'"),x.default.isPlainObject(i)||(i=new i),x.default.quacks(i,["buildView"])||(0,w.default)(23,"Invalid resolver for view: "+t),i)}},{key:"buildCaption",value:function(){var e=this.table,t=e.options.caption;return t?new c.VHtmlElement("div",{class:"king-table-caption"},new c.VHtmlElement("span",{},new c.VTextElement(t))):null}},{key:"build",value:function(){var e=this;return e.table.element?e.ensureLayout().update():e}},{key:"ensureLayout",value:function(){var e=this;if(e.rootElement)return e;var t=e.table,n=e.options,r=t.element,i=e.buildView(null,null,new c.VHtmlFragment(" ")),a=e.buildCaption(),s=e.buildRoot(a,i);return t.emit("empty:element",r),S.default.empty(r),S.default.addClass(r,"king-table"),r.innerHTML=s.toString(),e.rootElement=S.default.findFirstByClass(r,"king-table-region"),e.bindEvents(),x.default.ifcall(n.onLayoutRender,e,[r]),n.filtersView&&x.default.ifcall(n.onFiltersRender,e,[S.default.findFirstByClass(r,"kt-filters")]),e}},{key:"update",value:function(){this.updatePagination().updateView()}},{key:"updatePagination",value:function(){var e=this.table,t=e.pagination,n=this.rootElement;n||(0,w.default)(26,"missing root element");var r=this.getReg(),t=(e.options,e.pagination),i=t.page,a=t.totalPageCount,s=t.resultsPerPage,o=t.firstObjectNumber,u=t.lastObjectNumber,l=t.totalItemsCount,f=e.getFormattedAnchorTime(),c=x.default.isNumber,d=S.default.findFirstByClass,p=S.default.addClass,h=S.default.removeClass;d(n,"pagination-bar-page-number").value=i,d(n,"pagination-bar-results-select").value=s;var m="pagination-button",g="pagination-button-disabled";x.default.each(["pagination-bar-first-page","pagination-bar-prev-page"],function(e){var t=d(n,e);i>1?(p(t,m),h(t,g)):(p(t,g),h(t,m))}),x.default.each(["pagination-bar-last-page","pagination-bar-next-page"],function(e){var t=d(n,e);i0&&(v+=r.results+" "+o+" - "+u,c(l)&&(v+=" "+r.of+" - "+l));var y="";f&&e.options.showAnchorTimestamp&&(y=r.anchorTime+" "+f);var b,k={"results-info":v,"anchor-timestamp-info":y,"total-page-count":r.of+" "+a};for(b in k){var E=d(n,b);E&&(E.innerHTML=k[b])}var P=e.searchText||"",T=d(n,"search-field");return T&&T.value!=P&&0==S.default.isFocused(T)&&(T.value=P),this}},{key:"updateView",value:function(){var e=this,t=e.options,n=e.table,r=n.pagination,i=e.rootElement;i||(0,w.default)(26,"missing root element"),x.default.each({"kt-search-active":n.searchText,"kt-search-sorting":n.options.searchSortingRules},function(e,t){S.default.modClass(i,t,e)});var r=n.getData({format:!0,hide:!1}),a=S.default.findFirstByClass(i,"king-table-view");if(!r||!r.length)return a.innerHTML=e.emptyView().toString(),e;var s=e.getFields();if(e._must_build_tools){document.getElementById(e.toolsRegionId).innerHTML=e.buildToolsInner(!0),delete e._must_build_tools}e.currentItems=r;var o=e.buildView(s,r);return a.innerHTML=o.children[0].toString(),x.default.ifcall(t.onViewUpdate,e,[a]),e}},{key:"display",value:function(e){var t=(this.table,this.options);x.default.isString(e)||(e=e.toString()),this.ensureLayout();var n=this.rootElement,r=S.default.findFirstByClass(n,"king-table-view");r.innerHTML=e,x.default.ifcall(t.onViewUpdate,this,[r])}},{key:"buildRoot",value:function(e,t){var n=this.table,r={class:"king-table-region"};return n.id&&(r.id=n.id),new c.VHtmlElement("div",r,[e,this.buildPaginationBar(),this.buildFiltersView(),t])}},{key:"buildPaginationBar",value:function(){var e=this.table,t=this.getReg(),n=this.options,r=e.pagination,i=(r.page,r.totalPageCount,r.resultsPerPage,r.firstObjectNumber),a=r.lastObjectNumber,s=r.totalItemsCount,o=n.filtersView,u=o&&n.filtersViewExpandable,l=u&&n.filtersViewOpen,f=e.getFormattedAnchorTime(),d=x.default.isNumber,p="";d(i)&&d(a)&&a>0&&(p+=t.results+" "+i+" - "+a,d(s)&&(p+=" "+t.of+" - "+s));var h;f&&e.options.showAnchorTimestamp&&(h=t.anchorTime+" "+f);var m=t.advancedFilters,g=n.allowSearch?new c.VHtmlElement("span",{class:"pagination-bar-filters"},new c.VHtmlElement("input",{type:"text",class:"search-field",value:e.searchText||""})):null,v="span",y=new c.VHtmlElement(v,{class:"separator"});return new c.VHtmlElement("div",{class:"pagination-bar"},[this.buildTools(),new c.VHtmlElement(v,{class:"pagination-bar-buttons"},[new c.VHtmlElement(v,{tabindex:"0",class:"pagination-button pagination-bar-first-page oi","data-glyph":"media-step-backward",title:t.firstPage}),new c.VHtmlElement(v,{tabindex:"0",class:"pagination-button pagination-bar-prev-page oi","data-glyph":"caret-left",title:t.prevPage}),y,new c.VHtmlElement(v,{class:"valigned"},new c.VTextElement(t.page)),new c.VHtmlElement("input",{type:"text",name:"page-number",class:"must-integer pagination-bar-page-number",value:r.page}),new c.VHtmlElement("span",{class:"valigned total-page-count",value:r.page},new c.VTextElement(t.of+" "+r.totalPageCount)),y,new c.VHtmlElement(v,{tabindex:"0",class:"pagination-button pagination-bar-refresh oi","data-glyph":"reload",title:t.refresh}),y,new c.VHtmlElement(v,{tabindex:"0",class:"pagination-button pagination-bar-next-page oi","data-glyph":"caret-right",title:t.nextPage}),new c.VHtmlElement(v,{tabindex:"0",class:"pagination-button pagination-bar-last-page oi","data-glyph":"media-step-forward",title:t.lastPage}),y,new c.VHtmlElement(v,{class:"valigned"},new c.VTextElement(t.resultsPerPage)),new c.VHtmlElement("select",{name:"pageresults",class:"pagination-bar-results-select valigned"},x.default.map(n.resultsPerPageSelect,function(e){var t=new c.VHtmlElement("option",{value:e},new c.VTextElement(e.toString()));return e===n.resultsPerPage&&(t.attributes.selected=!0),t})),y,p?new c.VHtmlElement(v,{class:"valigned results-info"},new c.VTextElement(p)):null,p?y:null,h?new c.VHtmlElement(v,{class:"valigned anchor-timestamp-info"},new c.VTextElement(h)):null,g?y:null,g,u?y:null,u?new c.VHtmlElement("button",{class:"btn valigned camo-btn kt-advanced-filters"+(l?" kt-open":"")},new c.VTextElement(m)):null])])}},{key:"buildHead",value:function(e){var t=this.table,n=t.builder,r=t.sortCriteria,i=n.getReg(),a=new c.VHtmlElement("tr",{},x.default.map(x.default.values(e),function(e){if(!e.hidden&&!e.secret){var t,n=!1,a=[e.css];if(e.sortable){a.push("sortable");var s=x.default.find(r,function(t){return t[0]===e.name});s&&(n=!0,t=s[1])}var o=e.displayName;return new c.VHtmlElement("th",{class:a.join(" "),"data-prop":e.name},new c.VHtmlElement("div",{},[new c.VHtmlElement("span",{},new c.VTextElement(o)),n?new c.VHtmlElement("span",{class:"oi kt-sort-glyph","data-glyph":1==t?"sort-ascending":"sort-descending","aria-hidden":!0,title:x.default.format(1==t?i.sortAscendingBy:i.sortDescendingBy,{name:o})}):null]))}}));return new c.VHtmlElement("thead",{class:"king-table-head"},a)}},{key:"buildView",value:function(e,t,n){var r,i=this.table;if(n)r=n;else if(t&&t.length){var r,a=this.getViewResolver();a===this?r=new c.VHtmlElement("table",{class:"king-table"},[this.buildHead(e),this.buildBody(e,t)]):(a.table=this.table,a.options=i.options,r=a.buildView(i,e,t),delete a.table,delete a.options)}else r=new c.VHtmlElement("div",{class:"king-table-view"},this.emptyView());return new c.VHtmlElement("div",{class:"king-table-view"},r)}},{key:"getTemplate",value:function(e,t){if(x.default.isFunction(e))return e.call(this);x.default.isString(e)||(0,w.default)(38,"Cannot obtain HTML from given parameter "+t+", must be a function or a string.");var n=document.getElementById(e);if(null!=n){if(/script/i.test(n.tagName))return n.innerText;(0,w.default)(38,"Cannot obtain HTML from parameter "+t+". Element is not diff --git a/js/src/app/app.js b/js/src/app/app.js new file mode 100644 index 0000000..9da8c03 --- /dev/null +++ b/js/src/app/app.js @@ -0,0 +1,7 @@ +import { createApp } from 'vue' +import router from './router.js' +import App from './App.vue' + +createApp(App) + .use(router) + .mount('#content-vue') diff --git a/js/src/app/router.js b/js/src/app/router.js new file mode 100644 index 0000000..a99f795 --- /dev/null +++ b/js/src/app/router.js @@ -0,0 +1,31 @@ +import { createRouter, createWebHistory } from 'vue-router' +import { generateUrl } from '@nextcloud/router' +import PlaceholderView from './views/PlaceholderView.vue' + +const views = [ + { path: 'timer', name: 'timer', title: 'Timer' }, + { path: 'dashboard', name: 'dashboard', title: 'Dashboard' }, + { path: 'goals', name: 'goals', title: 'Goals' }, + { path: 'reports', name: 'reports', title: 'Reports' }, + { path: 'timelines', name: 'timelines', title: 'Timelines' }, + { path: 'timelines-admin', name: 'timelines-admin', title: 'Timelines Admin' }, + { path: 'projects', name: 'projects', title: 'Projects' }, + { path: 'clients', name: 'clients', title: 'Clients' }, + { path: 'tags', name: 'tags', title: 'Tags' }, +] + +const routes = views.map(({ path, name, title }) => ({ + path: `/${path}`, + name, + component: PlaceholderView, + props: { title }, +})) + +routes.push({ path: '/', redirect: '/timer' }) + +export default createRouter({ + history: createWebHistory(generateUrl('/apps/timetracker/spa')), + routes, +}) + +export { views } diff --git a/js/src/app/views/PlaceholderView.vue b/js/src/app/views/PlaceholderView.vue new file mode 100644 index 0000000..ba4b11e --- /dev/null +++ b/js/src/app/views/PlaceholderView.vue @@ -0,0 +1,37 @@ + + + diff --git a/js/webpack.config.js b/js/webpack.config.js index 384f39b..0696cbf 100644 --- a/js/webpack.config.js +++ b/js/webpack.config.js @@ -1,3 +1,11 @@ +const fs = require('fs'); +const webpack = require('webpack'); +const { VueLoaderPlugin } = require('vue-loader'); + +const appVersion = fs + .readFileSync(__dirname + '/../appinfo/info.xml', 'utf8') + .match(/([^<]+)<\/version>/)[1]; + module.exports = { //mode: 'development', devtool: 'cheap-module-source-map', @@ -11,6 +19,7 @@ module.exports = { goals: './src/goals.js', timelines: './src/timelines.js', timelinesadmin: './src/timelines-admin.js', + app: './src/app/app.js', }, output: { filename: '[name].js', @@ -23,6 +32,10 @@ module.exports = { }, module: { rules: [ + { + test: /\.vue$/, + loader: 'vue-loader', + }, { test: /\.css$/, use: ['style-loader', 'css-loader'], @@ -33,5 +46,12 @@ module.exports = { }, ] }, + plugins: [ + new VueLoaderPlugin(), + new webpack.DefinePlugin({ + appName: JSON.stringify('timetracker'), + appVersion: JSON.stringify(appVersion), + }), + ], }; diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 5599515..df3917e 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -29,5 +29,14 @@ public function index() { return new TemplateResponse('timetracker', 'index',['appPage' => 'content/index', 'script' => 'dist/timer']); // templates/index.php } + /** + * + * @NoAdminRequired + * @NoCSRFRequired + */ + public function spa($path = '') { + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php + } + } diff --git a/templates/navigation/index.php b/templates/navigation/index.php index 8a1d4c4..7c2f770 100644 --- a/templates/navigation/index.php +++ b/templates/navigation/index.php @@ -11,4 +11,5 @@
  • Projects
  • Clients
  • Tags
  • +
  • SPA Preview (WIP)
  • diff --git a/templates/spa.php b/templates/spa.php new file mode 100644 index 0000000..2575304 --- /dev/null +++ b/templates/spa.php @@ -0,0 +1,7 @@ + + +
    From b5d10635dc7dfe36145124ca6abeeeee8ecb3f6d Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 13 Jul 2026 00:08:03 +0200 Subject: [PATCH 07/12] Migrate all views to the Vue SPA (Stages 2-4 of frontend migration) Completes the jQuery-to-Vue migration started in Stage 1: every view (timer, dashboard, goals, reports, timelines, timelines-admin, projects, clients, tags) is now a Vue component backed by the same unchanged AjaxController endpoints. All 9 controllers now render the single SPA shell, so the classic per-view PHP templates and their dedicated webpack bundles are gone. Also drops the now-unused legacy stack: jquery, jquery-migrate, jqueryui, select2, daterangepicker, tabulator-tables, moment, piklor.js, and chart.js v2 (replaced by chart.js v4 + vue-chartjs for the dashboard's time/cost breakdown charts), along with their CSS and font assets. Bumps the app version so Nextcloud's asset cache-busting URL changes and browsers pick up the new bundle instead of serving a stale cached copy under the old unchanged URL. Co-Authored-By: Claude Sonnet 5 --- appinfo/info.xml | 2 +- appinfo/routes.php | 1 - css/daterangepicker.css | 421 ----------- css/fonts/FONT-LICENSE | 86 --- css/fonts/ICON-LICENSE | 21 - css/fonts/github-link | 1 - css/fonts/open-iconic.eot | Bin 28196 -> 0 bytes css/fonts/open-iconic.otf | Bin 20996 -> 0 bytes css/fonts/open-iconic.svg | 1 - css/fonts/open-iconic.ttf | Bin 28028 -> 0 bytes css/fonts/open-iconic.woff | Bin 14984 -> 0 bytes css/piklor.css | 67 -- css/select2.css | 484 ------------ css/select2.min.css | 1 - css/style-compat.css | 74 -- css/style.css | 583 --------------- css/tabulator.css | 769 -------------------- img/play-button.svg | 1 - img/stop-button.svg | 1 - js/package-lock.json | 260 +++---- js/package.json | 12 +- js/src/app/api.js | 19 + js/src/app/router.js | 37 +- js/src/app/views/ClientsView.vue | 165 +++++ js/src/app/views/DashboardView.vue | 169 +++++ js/src/app/views/GoalsView.vue | 164 +++++ js/src/app/views/PlaceholderView.vue | 37 - js/src/app/views/ProjectsView.vue | 282 +++++++ js/src/app/views/ReportsView.vue | 214 ++++++ js/src/app/views/TagsView.vue | 165 +++++ js/src/app/views/TimelinesAdminView.vue | 136 ++++ js/src/app/views/TimelinesView.vue | 286 ++++++++ js/src/app/views/TimerView.vue | 391 ++++++++++ js/src/clients.js | 168 ----- js/src/dashboard.js | 319 -------- js/src/dateformat.js | 53 -- js/src/goals.js | 163 ----- js/src/piklor.js | 161 ---- js/src/projects.js | 487 ------------- js/src/reports.js | 296 -------- js/src/tags.js | 158 ---- js/src/timelines-admin.js | 180 ----- js/src/timelines.js | 417 ----------- js/src/timer.js | 678 ----------------- js/webpack.config.js | 14 - lib/Controller/ClientsController.php | 2 +- lib/Controller/DashboardController.php | 2 +- lib/Controller/GoalsController.php | 2 +- lib/Controller/PageController.php | 9 - lib/Controller/ProjectsController.php | 2 +- lib/Controller/ReportsController.php | 2 +- lib/Controller/TagsController.php | 2 +- lib/Controller/TimelinesAdminController.php | 2 +- lib/Controller/TimelinesController.php | 2 +- templates/content/clients.php | 28 - templates/content/dashboard.php | 22 - templates/content/goals.php | 26 - templates/content/index.php | 69 -- templates/content/projects.php | 81 --- templates/content/reports.php | 79 -- templates/content/tags.php | 28 - templates/content/timelines-admin.php | 43 -- templates/content/timelines.php | 102 --- templates/index.php | 23 - templates/navigation/index.php | 15 - 65 files changed, 2135 insertions(+), 6350 deletions(-) delete mode 100644 css/daterangepicker.css delete mode 100644 css/fonts/FONT-LICENSE delete mode 100644 css/fonts/ICON-LICENSE delete mode 100644 css/fonts/github-link delete mode 100644 css/fonts/open-iconic.eot delete mode 100644 css/fonts/open-iconic.otf delete mode 100644 css/fonts/open-iconic.svg delete mode 100644 css/fonts/open-iconic.ttf delete mode 100644 css/fonts/open-iconic.woff delete mode 100644 css/piklor.css delete mode 100644 css/select2.css delete mode 100644 css/select2.min.css delete mode 100644 css/style-compat.css delete mode 100644 css/style.css delete mode 100644 css/tabulator.css delete mode 100644 img/play-button.svg delete mode 100644 img/stop-button.svg create mode 100644 js/src/app/api.js create mode 100644 js/src/app/views/ClientsView.vue create mode 100644 js/src/app/views/DashboardView.vue create mode 100644 js/src/app/views/GoalsView.vue delete mode 100644 js/src/app/views/PlaceholderView.vue create mode 100644 js/src/app/views/ProjectsView.vue create mode 100644 js/src/app/views/ReportsView.vue create mode 100644 js/src/app/views/TagsView.vue create mode 100644 js/src/app/views/TimelinesAdminView.vue create mode 100644 js/src/app/views/TimelinesView.vue create mode 100644 js/src/app/views/TimerView.vue delete mode 100644 js/src/clients.js delete mode 100644 js/src/dashboard.js delete mode 100644 js/src/dateformat.js delete mode 100644 js/src/goals.js delete mode 100644 js/src/piklor.js delete mode 100644 js/src/projects.js delete mode 100644 js/src/reports.js delete mode 100644 js/src/tags.js delete mode 100644 js/src/timelines-admin.js delete mode 100644 js/src/timelines.js delete mode 100644 js/src/timer.js delete mode 100644 templates/content/clients.php delete mode 100644 templates/content/dashboard.php delete mode 100644 templates/content/goals.php delete mode 100644 templates/content/index.php delete mode 100644 templates/content/projects.php delete mode 100644 templates/content/reports.php delete mode 100644 templates/content/tags.php delete mode 100644 templates/content/timelines-admin.php delete mode 100644 templates/content/timelines.php delete mode 100644 templates/index.php delete mode 100644 templates/navigation/index.php diff --git a/appinfo/info.xml b/appinfo/info.xml index 45c38f9..61780a9 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -35,7 +35,7 @@ Mit dem integrierten Dashboard lässt sich anhand eines Kuchen-/Donut-Diagramms Diese App wird aktuell noch weiterentwickelt, also: Augen offen halten für neue Features! Und falls Dir irgendwelche Verbesserungsvorschläge, Probleme oder neue Features einfallen, schau mal auf unserem [GitHub Projekt](https://github.com/mtierltd/timetracker) vorbei, vielleicht wird Dein Thema bereits diskutiert! Und falls nicht, starte gerne eine neue Diskussion, wir freuen uns auf Dein Feedback! - 0.0.87 + 0.0.88 agpl MTier Ltd. TimeTracker diff --git a/appinfo/routes.php b/appinfo/routes.php index e10ca60..ebb203b 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -13,7 +13,6 @@ 'routes' => [ ['name' => 'page#index', 'url' => '/', 'verb' => 'GET'], ['name' => 'page#do_echo', 'url' => '/echo', 'verb' => 'POST'], - ['name' => 'page#spa', 'url' => '/spa/{path}', 'verb' => 'GET', 'requirements' => ['path' => '.*'], 'defaults' => ['path' => '']], ['name' => 'clients#index', 'url' => '/clients', 'verb' => 'GET'], ['name' => 'projects#index', 'url' => '/projects', 'verb' => 'GET'], ['name' => 'dashboard#index', 'url' => '/dashboard', 'verb' => 'GET'], diff --git a/css/daterangepicker.css b/css/daterangepicker.css deleted file mode 100644 index 62c21cb..0000000 --- a/css/daterangepicker.css +++ /dev/null @@ -1,421 +0,0 @@ -.daterangepicker { - position: absolute; - color: inherit; - background-color: #fff; - border-radius: 4px; - border: 1px solid #ddd; - width: 278px; - max-width: none; - padding: 0; - margin-top: 7px; - top: 100px; - left: 20px; - z-index: 3001; - display: none; - font-family: arial; - font-size: 15px; - line-height: 1em; -} - -.daterangepicker:before, .daterangepicker:after { - position: absolute; - display: inline-block; - border-bottom-color: rgba(0, 0, 0, 0.2); - content: ''; -} - -.daterangepicker:before { - top: -7px; - border-right: 7px solid transparent; - border-left: 7px solid transparent; - border-bottom: 7px solid #ccc; -} - -.daterangepicker:after { - top: -6px; - border-right: 6px solid transparent; - border-bottom: 6px solid #fff; - border-left: 6px solid transparent; -} - -.daterangepicker.opensleft:before { - right: 9px; -} - -.daterangepicker.opensleft:after { - right: 10px; -} - -.daterangepicker.openscenter:before { - left: 0; - right: 0; - width: 0; - margin-left: auto; - margin-right: auto; -} - -.daterangepicker.openscenter:after { - left: 0; - right: 0; - width: 0; - margin-left: auto; - margin-right: auto; -} - -.daterangepicker.opensright:before { - left: 9px; -} - -.daterangepicker.opensright:after { - left: 10px; -} - -.daterangepicker.drop-up { - margin-top: -7px; -} - -.daterangepicker.drop-up:before { - top: initial; - bottom: -7px; - border-bottom: initial; - border-top: 7px solid #ccc; -} - -.daterangepicker.drop-up:after { - top: initial; - bottom: -6px; - border-bottom: initial; - border-top: 6px solid #fff; -} - -.daterangepicker.single .daterangepicker .ranges, .daterangepicker.single .drp-calendar { - float: none; -} - -.daterangepicker.single .drp-selected { - display: none; -} - -.daterangepicker.show-calendar .drp-calendar { - display: block; -} - -.daterangepicker.show-calendar .drp-buttons { - display: block; -} - -.daterangepicker.auto-apply .drp-buttons { - display: none; -} - -.daterangepicker .drp-calendar { - display: none; - max-width: 270px; -} - -.daterangepicker .drp-calendar.left { - padding: 8px 0 8px 8px; -} - -.daterangepicker .drp-calendar.right { - padding: 8px; -} - -.daterangepicker .drp-calendar.single .calendar-table { - border: none; -} - -.daterangepicker .calendar-table .next span, .daterangepicker .calendar-table .prev span { - color: #fff; - border: solid black; - border-width: 0 2px 2px 0; - border-radius: 0; - display: inline-block; - padding: 3px; -} - -.daterangepicker .calendar-table .next span { - transform: rotate(-45deg); - -webkit-transform: rotate(-45deg); -} - -.daterangepicker .calendar-table .prev span { - transform: rotate(135deg); - -webkit-transform: rotate(135deg); -} - -.daterangepicker .calendar-table th, .daterangepicker .calendar-table td { - white-space: nowrap; - text-align: center; - vertical-align: middle; - min-width: 32px; - width: 32px; - height: 24px; - line-height: 24px; - font-size: 12px; - border-radius: 4px; - border: 1px solid transparent; - white-space: nowrap; - cursor: pointer; -} - -.daterangepicker .calendar-table { - border: 1px solid #fff; - border-radius: 4px; - background-color: #fff; -} - -.daterangepicker .calendar-table table { - width: 100%; - margin: 0; - border-spacing: 0; - border-collapse: collapse; -} - -.daterangepicker td.available:hover, .daterangepicker th.available:hover { - background-color: #eee; - border-color: transparent; - color: inherit; -} - -.daterangepicker td.week, .daterangepicker th.week { - font-size: 80%; - color: #ccc; -} - -.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date { - background-color: #fff; - border-color: transparent; - color: #999; -} - -.daterangepicker td.in-range { - background-color: #ebf4f8; - border-color: transparent; - color: #000; - border-radius: 0; -} - -.daterangepicker td.start-date { - border-radius: 4px 0 0 4px; -} - -.daterangepicker td.end-date { - border-radius: 0 4px 4px 0; -} - -.daterangepicker td.start-date.end-date { - border-radius: 4px; -} - -.daterangepicker td.active, .daterangepicker td.active:hover { - background-color: #357ebd; - border-color: transparent; - color: #fff; -} - -.daterangepicker th.month { - width: auto; -} - -.daterangepicker td.disabled, .daterangepicker option.disabled { - color: #999; - cursor: not-allowed; - text-decoration: line-through; -} - -.daterangepicker select.monthselect, .daterangepicker select.yearselect { - font-size: 12px; - padding: 1px; - height: auto; - margin: 0; - cursor: default; -} - -.daterangepicker select.monthselect { - margin-right: 2%; - width: 56%; -} - -.daterangepicker select.yearselect { - width: 40%; -} - -.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect { - width: 50px; - margin: 0 auto; - background: #eee; - border: 1px solid #eee; - padding: 2px; - outline: 0; - font-size: 12px; -} - -.daterangepicker .calendar-time { - text-align: center; - margin: 4px auto 0 auto; - line-height: 30px; - position: relative; -} - -.daterangepicker .calendar-time select.disabled { - color: #ccc; - cursor: not-allowed; -} - -.daterangepicker .drp-buttons { - clear: both; - text-align: right; - padding: 8px; - border-top: 1px solid #ddd; - display: none; - line-height: 12px; - vertical-align: middle; -} - -.daterangepicker .drp-selected { - display: inline-block; - font-size: 12px; - padding-right: 8px; -} - -.daterangepicker .drp-buttons .btn { - margin-left: 8px; - font-size: 12px; - font-weight: bold; - padding: 4px 8px; -} - -.daterangepicker.show-ranges .drp-calendar.left { - border-left: 1px solid #ddd; -} - -.daterangepicker .ranges { - float: none; - text-align: left; - margin: 0; -} - -.daterangepicker.show-calendar .ranges { - margin-top: 8px; -} - -.daterangepicker .ranges ul { - list-style: none; - margin: 0 auto; - padding: 0; - width: 100%; -} - -.daterangepicker .ranges li { - font-size: 12px; - padding: 8px 12px; - cursor: pointer; -} - -.daterangepicker .ranges li:hover { - background-color: #eee; -} - -.daterangepicker .ranges li.active { - background-color: #08c; - color: #fff; -} - -/* Larger Screen Styling */ -@media (min-width: 564px) { - .daterangepicker { - width: auto; } - .daterangepicker .ranges ul { - width: 140px; } - .daterangepicker.single .ranges ul { - width: 100%; } - .daterangepicker.single .drp-calendar.left { - clear: none; } - .daterangepicker.single.ltr .ranges, .daterangepicker.single.ltr .drp-calendar { - float: left; } - .daterangepicker.single.rtl .ranges, .daterangepicker.single.rtl .drp-calendar { - float: right; } - .daterangepicker.ltr { - direction: ltr; - text-align: left; } - .daterangepicker.ltr .drp-calendar.left { - clear: left; - margin-right: 0; } - .daterangepicker.ltr .drp-calendar.left .calendar-table { - border-right: none; - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - .daterangepicker.ltr .drp-calendar.right { - margin-left: 0; } - .daterangepicker.ltr .drp-calendar.right .calendar-table { - border-left: none; - border-top-left-radius: 0; - border-bottom-left-radius: 0; } - .daterangepicker.ltr .drp-calendar.left .calendar-table { - padding-right: 8px; } - .daterangepicker.ltr .ranges, .daterangepicker.ltr .drp-calendar { - float: left; } - .daterangepicker.rtl { - direction: rtl; - text-align: right; } - .daterangepicker.rtl .drp-calendar.left { - clear: right; - margin-left: 0; } - .daterangepicker.rtl .drp-calendar.left .calendar-table { - border-left: none; - border-top-left-radius: 0; - border-bottom-left-radius: 0; } - .daterangepicker.rtl .drp-calendar.right { - margin-right: 0; } - .daterangepicker.rtl .drp-calendar.right .calendar-table { - border-right: none; - border-top-right-radius: 0; - border-bottom-right-radius: 0; } - .daterangepicker.rtl .drp-calendar.left .calendar-table { - padding-left: 12px; } - .daterangepicker.rtl .ranges, .daterangepicker.rtl .drp-calendar { - text-align: right; - float: right; } } -@media (min-width: 730px) { - .daterangepicker .ranges { - width: auto; } - .daterangepicker.ltr .ranges { - float: left; } - .daterangepicker.rtl .ranges { - float: right; } - .daterangepicker .drp-calendar.left { - clear: none !important; } } -.daterangepicker { - background-color: var(--color-main-background); -} -.daterangepicker .calendar-table { - border: 1px solid var(--color-main-background); - border-radius: 4px; - background-color: var(--color-main-background); -} -.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect { - width: 50px; - margin: 0 auto; - background:var(--color-background-dark); - border: 1px solid var(--color-background-dark); - padding: 2px; - outline: 0; - font-size: 12px; -} - -.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date { - background-color:var(--color-main-background); - border-color: transparent; - color: var(--color-background-darker); -} - -.daterangepicker td.available:hover, .daterangepicker th.available:hover { - background-color: var(--color-background-darker); - border-color: transparent; - color: inherit; -} -.daterangepicker .ranges li:hover { - background-color: var(--color-background-darker); -} - diff --git a/css/fonts/FONT-LICENSE b/css/fonts/FONT-LICENSE deleted file mode 100644 index a1dc03f..0000000 --- a/css/fonts/FONT-LICENSE +++ /dev/null @@ -1,86 +0,0 @@ -SIL OPEN FONT LICENSE Version 1.1 - -Copyright (c) 2014 Waybury - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/css/fonts/ICON-LICENSE b/css/fonts/ICON-LICENSE deleted file mode 100644 index 2199f4a..0000000 --- a/css/fonts/ICON-LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2014 Waybury - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file diff --git a/css/fonts/github-link b/css/fonts/github-link deleted file mode 100644 index 2907ace..0000000 --- a/css/fonts/github-link +++ /dev/null @@ -1 +0,0 @@ -https://github.com/iconic/open-iconic \ No newline at end of file diff --git a/css/fonts/open-iconic.eot b/css/fonts/open-iconic.eot deleted file mode 100644 index f98177dbf711863eff7c90f84d5d419d02d99ba8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28196 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 by FontForge 20120731 at Tue Jul 1 20:39:22 2014 By P.J. Onori Created by P.J. Onori with FontForge 2.0 (http://fontforge.sf.net) \ No newline at end of file diff --git a/css/fonts/open-iconic.ttf b/css/fonts/open-iconic.ttf deleted file mode 100644 index fab604866cd5e55ef4525ea22e420c411f510b01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28028 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 diff --git a/css/fonts/open-iconic.woff b/css/fonts/open-iconic.woff deleted file mode 100644 index f9309988aeab3868040d3b322658902098eba27f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 14984 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 diff --git a/css/piklor.css b/css/piklor.css deleted file mode 100644 index a43d6c9..0000000 --- a/css/piklor.css +++ /dev/null @@ -1,67 +0,0 @@ -/* -header, footer { - color: white; - background: #303F9F; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.51); -} - -h1.title { - font-size: 4em; - font-weight: bold; -} - -pre { - background: #212121; - color: white; -} - -header p { - font-size: 1.4em; -} - -footer { - padding: 50px 0; - text-align: center; - font-size: 1.1em; - margin-top: 3em; -} - -footer a { - color: white; -} - -footer a:hover { - color: white; -} -*/ -/* picker */ -.color-picker { - background: rgba(255, 255, 255, 0.75); - padding: 10px; - border: 1px solid rgba(203, 203, 203, 0.6); - border-radius: 2px; - position: absolute; - margin-left: -120px; - width: 300px; - z-index: 10; - margin-top: 35px; -} - -.color-picker > div { - width: 20px; - display: inline-block; - height: 20px; - margin: 3px; - border-radius: 100%; - opacity: 0.7; - -} - -.picker-wrapper { - padding: 20px; - display: inline; -} - -.color-picker > div:hover { - opacity: 1; -} \ No newline at end of file diff --git a/css/select2.css b/css/select2.css deleted file mode 100644 index ce3afd1..0000000 --- a/css/select2.css +++ /dev/null @@ -1,484 +0,0 @@ -.select2-container { - box-sizing: border-box; - display: inline-block; - margin: 0; - position: relative; - vertical-align: middle; } - .select2-container .select2-selection--single { - box-sizing: border-box; - cursor: pointer; - display: block; - height: 28px; - user-select: none; - -webkit-user-select: none; } - .select2-container .select2-selection--single .select2-selection__rendered { - display: block; - padding-left: 8px; - padding-right: 20px; - overflow: hidden; - text-overflow: ellipsis; - white-space: nowrap; } - .select2-container .select2-selection--single .select2-selection__clear { - position: relative; } - .select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered { - padding-right: 8px; - padding-left: 20px; } - .select2-container .select2-selection--multiple { - box-sizing: border-box; - cursor: pointer; - display: block; - min-height: 32px; - user-select: none; - -webkit-user-select: none; } - .select2-container .select2-selection--multiple .select2-selection__rendered { - display: inline-block; - overflow: hidden; - padding-left: 8px; - text-overflow: ellipsis; - white-space: nowrap; } - .select2-container .select2-search--inline { - float: left; } - .select2-container .select2-search--inline .select2-search__field { - box-sizing: border-box; - border: none; - font-size: 100%; - margin-top: 5px; - padding: 0; } - .select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button { - -webkit-appearance: none; } - -.select2-dropdown { - background-color: white; - border: 1px solid #aaa; - border-radius: 4px; - box-sizing: border-box; - display: block; - position: absolute; - left: -100000px; - width: 100%; - z-index: 1051; } - -.select2-results { - display: block; } - -.select2-results__options { - list-style: none; - margin: 0; - padding: 0; } - -.select2-results__option { - padding: 6px; - user-select: none; - -webkit-user-select: none; } - .select2-results__option[aria-selected] { - cursor: pointer; } - -.select2-container--open .select2-dropdown { - left: 0; } - -.select2-container--open .select2-dropdown--above { - border-bottom: none; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; } - -.select2-container--open .select2-dropdown--below { - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.select2-search--dropdown { - display: block; - padding: 4px; } - .select2-search--dropdown .select2-search__field { - padding: 4px; - width: 100%; - box-sizing: border-box; } - .select2-search--dropdown .select2-search__field::-webkit-search-cancel-button { - -webkit-appearance: none; } - .select2-search--dropdown.select2-search--hide { - display: none; } - -.select2-close-mask { - border: 0; - margin: 0; - padding: 0; - display: block; - position: fixed; - left: 0; - top: 0; - min-height: 100%; - min-width: 100%; - height: auto; - width: auto; - opacity: 0; - z-index: 99; - background-color: #fff; - filter: alpha(opacity=0); } - -.select2-hidden-accessible { - border: 0 !important; - clip: rect(0 0 0 0) !important; - -webkit-clip-path: inset(50%) !important; - clip-path: inset(50%) !important; - height: 1px !important; - overflow: hidden !important; - padding: 0 !important; - position: absolute !important; - width: 1px !important; - white-space: nowrap !important; } - -.select2-container--default .select2-selection--single { - background-color: #fff; - border: 1px solid #aaa; - border-radius: 4px; } - .select2-container--default .select2-selection--single .select2-selection__rendered { - color: #444; - line-height: 28px; } - .select2-container--default .select2-selection--single .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; } - .select2-container--default .select2-selection--single .select2-selection__placeholder { - color: #999; } - .select2-container--default .select2-selection--single .select2-selection__arrow { - height: 26px; - position: absolute; - top: 1px; - right: 1px; - width: 20px; } - .select2-container--default .select2-selection--single .select2-selection__arrow b { - border-color: #888 transparent transparent transparent; - border-style: solid; - border-width: 5px 4px 0 4px; - height: 0; - left: 50%; - margin-left: -4px; - margin-top: -2px; - position: absolute; - top: 50%; - width: 0; } - -.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear { - float: left; } - -.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow { - left: 1px; - right: auto; } - -.select2-container--default.select2-container--disabled .select2-selection--single { - background-color: #eee; - cursor: default; } - .select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear { - display: none; } - -.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b { - border-color: transparent transparent #888 transparent; - border-width: 0 4px 5px 4px; } - -.select2-container--default .select2-selection--multiple { - background-color: white; - border: 1px solid #aaa; - border-radius: 4px; - cursor: text; } - .select2-container--default .select2-selection--multiple .select2-selection__rendered { - box-sizing: border-box; - list-style: none; - margin: 0; - padding: 0 5px; - width: 100%; } - .select2-container--default .select2-selection--multiple .select2-selection__rendered li { - list-style: none; } - .select2-container--default .select2-selection--multiple .select2-selection__placeholder { - color: #999; - margin-top: 5px; - float: left; } - .select2-container--default .select2-selection--multiple .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; - margin-top: 5px; - margin-right: 10px; } - .select2-container--default .select2-selection--multiple .select2-selection__choice { - background-color: #e4e4e4; - border: 1px solid #aaa; - border-radius: 4px; - cursor: default; - float: left; - margin-right: 5px; - margin-top: 5px; - padding: 0 5px; } - .select2-container--default .select2-selection--multiple .select2-selection__choice__remove { - color: #999; - cursor: pointer; - display: inline-block; - font-weight: bold; - margin-right: 2px; } - .select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover { - color: #333; } - -.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder, .select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline { - float: right; } - -.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice { - margin-left: 5px; - margin-right: auto; } - -.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { - margin-left: 2px; - margin-right: auto; } - -.select2-container--default.select2-container--focus .select2-selection--multiple { - border: solid black 1px; - outline: 0; } - -.select2-container--default.select2-container--disabled .select2-selection--multiple { - background-color: #eee; - cursor: default; } - -.select2-container--default.select2-container--disabled .select2-selection__choice__remove { - display: none; } - -.select2-container--default.select2-container--open.select2-container--above .select2-selection--single, .select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple { - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.select2-container--default.select2-container--open.select2-container--below .select2-selection--single, .select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple { - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; } - -.select2-container--default .select2-search--dropdown .select2-search__field { - border: 1px solid #aaa; } - -.select2-container--default .select2-search--inline .select2-search__field { - background: transparent; - border: none; - outline: 0; - box-shadow: none; - -webkit-appearance: textfield; } - -.select2-container--default .select2-results > .select2-results__options { - max-height: 200px; - overflow-y: auto; } - -.select2-container--default .select2-results__option[role=group] { - padding: 0; } - -.select2-container--default .select2-results__option[aria-disabled=true] { - color: #999; } - -.select2-container--default .select2-results__option[aria-selected=true] { - background-color: #ddd; } - -.select2-container--default .select2-results__option .select2-results__option { - padding-left: 1em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__group { - padding-left: 0; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option { - margin-left: -1em; - padding-left: 2em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -2em; - padding-left: 3em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -3em; - padding-left: 4em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -4em; - padding-left: 5em; } - .select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option { - margin-left: -5em; - padding-left: 6em; } - -.select2-container--default .select2-results__option--highlighted[aria-selected] { - background-color: #5897fb; - color: white; } - -.select2-container--default .select2-results__group { - cursor: default; - display: block; - padding: 6px; } - -.select2-container--classic .select2-selection--single { - background-color: #f7f7f7; - border: 1px solid #aaa; - border-radius: 4px; - outline: 0; - background-image: -webkit-linear-gradient(top, white 50%, #eeeeee 100%); - background-image: -o-linear-gradient(top, white 50%, #eeeeee 100%); - background-image: linear-gradient(to bottom, white 50%, #eeeeee 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } - .select2-container--classic .select2-selection--single:focus { - border: 1px solid #5897fb; } - .select2-container--classic .select2-selection--single .select2-selection__rendered { - color: #444; - line-height: 28px; } - .select2-container--classic .select2-selection--single .select2-selection__clear { - cursor: pointer; - float: right; - font-weight: bold; - margin-right: 10px; } - .select2-container--classic .select2-selection--single .select2-selection__placeholder { - color: #999; } - .select2-container--classic .select2-selection--single .select2-selection__arrow { - background-color: #ddd; - border: none; - border-left: 1px solid #aaa; - border-top-right-radius: 4px; - border-bottom-right-radius: 4px; - height: 26px; - position: absolute; - top: 1px; - right: 1px; - width: 20px; - background-image: -webkit-linear-gradient(top, #eeeeee 50%, #cccccc 100%); - background-image: -o-linear-gradient(top, #eeeeee 50%, #cccccc 100%); - background-image: linear-gradient(to bottom, #eeeeee 50%, #cccccc 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0); } - .select2-container--classic .select2-selection--single .select2-selection__arrow b { - border-color: #888 transparent transparent transparent; - border-style: solid; - border-width: 5px 4px 0 4px; - height: 0; - left: 50%; - margin-left: -4px; - margin-top: -2px; - position: absolute; - top: 50%; - width: 0; } - -.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear { - float: left; } - -.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow { - border: none; - border-right: 1px solid #aaa; - border-radius: 0; - border-top-left-radius: 4px; - border-bottom-left-radius: 4px; - left: 1px; - right: auto; } - -.select2-container--classic.select2-container--open .select2-selection--single { - border: 1px solid #5897fb; } - .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow { - background: transparent; - border: none; } - .select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b { - border-color: transparent transparent #888 transparent; - border-width: 0 4px 5px 4px; } - -.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single { - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; - background-image: -webkit-linear-gradient(top, white 0%, #eeeeee 50%); - background-image: -o-linear-gradient(top, white 0%, #eeeeee 50%); - background-image: linear-gradient(to bottom, white 0%, #eeeeee 50%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0); } - -.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single { - border-bottom: none; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; - background-image: -webkit-linear-gradient(top, #eeeeee 50%, white 100%); - background-image: -o-linear-gradient(top, #eeeeee 50%, white 100%); - background-image: linear-gradient(to bottom, #eeeeee 50%, white 100%); - background-repeat: repeat-x; - filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0); } - -.select2-container--classic .select2-selection--multiple { - background-color: white; - border: 1px solid #aaa; - border-radius: 4px; - cursor: text; - outline: 0; } - .select2-container--classic .select2-selection--multiple:focus { - border: 1px solid #5897fb; } - .select2-container--classic .select2-selection--multiple .select2-selection__rendered { - list-style: none; - margin: 0; - padding: 0 5px; } - .select2-container--classic .select2-selection--multiple .select2-selection__clear { - display: none; } - .select2-container--classic .select2-selection--multiple .select2-selection__choice { - background-color: #e4e4e4; - border: 1px solid #aaa; - border-radius: 4px; - cursor: default; - float: left; - margin-right: 5px; - margin-top: 5px; - padding: 0 5px; } - .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove { - color: #888; - cursor: pointer; - display: inline-block; - font-weight: bold; - margin-right: 2px; } - .select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover { - color: #555; } - -.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice { - float: right; - margin-left: 5px; - margin-right: auto; } - -.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove { - margin-left: 2px; - margin-right: auto; } - -.select2-container--classic.select2-container--open .select2-selection--multiple { - border: 1px solid #5897fb; } - -.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple { - border-top: none; - border-top-left-radius: 0; - border-top-right-radius: 0; } - -.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple { - border-bottom: none; - border-bottom-left-radius: 0; - border-bottom-right-radius: 0; } - -.select2-container--classic .select2-search--dropdown .select2-search__field { - border: 1px solid #aaa; - outline: 0; } - -.select2-container--classic .select2-search--inline .select2-search__field { - outline: 0; - box-shadow: none; } - -.select2-container--classic .select2-dropdown { - background-color: white; - border: 1px solid transparent; } - -.select2-container--classic .select2-dropdown--above { - border-bottom: none; } - -.select2-container--classic .select2-dropdown--below { - border-top: none; } - -.select2-container--classic .select2-results > .select2-results__options { - max-height: 200px; - overflow-y: auto; } - -.select2-container--classic .select2-results__option[role=group] { - padding: 0; } - -.select2-container--classic .select2-results__option[aria-disabled=true] { - color: grey; } - -.select2-container--classic .select2-results__option--highlighted[aria-selected] { - background-color: #3875d7; - color: white; } - -.select2-container--classic .select2-results__group { - cursor: default; - display: block; - padding: 6px; } - -.select2-container--classic.select2-container--open .select2-dropdown { - border-color: #5897fb; } diff --git a/css/select2.min.css b/css/select2.min.css deleted file mode 100644 index 60d5990..0000000 --- a/css/select2.min.css +++ /dev/null @@ -1 +0,0 @@ -.select2-container{box-sizing:border-box;display:inline-block;margin:0;position:relative;vertical-align:middle}.select2-container .select2-selection--single{box-sizing:border-box;cursor:pointer;display:block;height:28px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--single .select2-selection__rendered{display:block;padding-left:8px;padding-right:20px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-selection--single .select2-selection__clear{position:relative}.select2-container[dir="rtl"] .select2-selection--single .select2-selection__rendered{padding-right:8px;padding-left:20px}.select2-container .select2-selection--multiple{box-sizing:border-box;cursor:pointer;display:block;min-height:32px;user-select:none;-webkit-user-select:none}.select2-container .select2-selection--multiple .select2-selection__rendered{display:inline-block;overflow:hidden;padding-left:8px;text-overflow:ellipsis;white-space:nowrap}.select2-container .select2-search--inline{float:left}.select2-container .select2-search--inline .select2-search__field{box-sizing:border-box;border:none;font-size:100%;margin-top:5px;padding:0}.select2-container .select2-search--inline .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-dropdown{background-color:white;border:1px solid #aaa;border-radius:4px;box-sizing:border-box;display:block;position:absolute;left:-100000px;width:100%;z-index:1051}.select2-results{display:block}.select2-results__options{list-style:none;margin:0;padding:0}.select2-results__option{padding:6px;user-select:none;-webkit-user-select:none}.select2-results__option[aria-selected]{cursor:pointer}.select2-container--open .select2-dropdown{left:0}.select2-container--open .select2-dropdown--above{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--open .select2-dropdown--below{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-search--dropdown{display:block;padding:4px}.select2-search--dropdown .select2-search__field{padding:4px;width:100%;box-sizing:border-box}.select2-search--dropdown .select2-search__field::-webkit-search-cancel-button{-webkit-appearance:none}.select2-search--dropdown.select2-search--hide{display:none}.select2-close-mask{border:0;margin:0;padding:0;display:block;position:fixed;left:0;top:0;min-height:100%;min-width:100%;height:auto;width:auto;opacity:0;z-index:99;background-color:#fff;filter:alpha(opacity=0)}.select2-hidden-accessible{border:0 !important;clip:rect(0 0 0 0) !important;-webkit-clip-path:inset(50%) !important;clip-path:inset(50%) !important;height:1px !important;overflow:hidden !important;padding:0 !important;position:absolute !important;width:1px !important;white-space:nowrap !important}.select2-container--default .select2-selection--single{background-color:#fff;border:1px solid #aaa;border-radius:4px}.select2-container--default .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--default .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold}.select2-container--default .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--default .select2-selection--single .select2-selection__arrow{height:26px;position:absolute;top:1px;right:1px;width:20px}.select2-container--default .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--default[dir="rtl"] .select2-selection--single .select2-selection__arrow{left:1px;right:auto}.select2-container--default.select2-container--disabled .select2-selection--single{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection--single .select2-selection__clear{display:none}.select2-container--default.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--default .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text}.select2-container--default .select2-selection--multiple .select2-selection__rendered{box-sizing:border-box;list-style:none;margin:0;padding:0 5px;width:100%}.select2-container--default .select2-selection--multiple .select2-selection__rendered li{list-style:none}.select2-container--default .select2-selection--multiple .select2-selection__placeholder{color:#999;margin-top:5px;float:left}.select2-container--default .select2-selection--multiple .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-top:5px;margin-right:10px}.select2-container--default .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove{color:#999;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--default .select2-selection--multiple .select2-selection__choice__remove:hover{color:#333}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__placeholder,.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-search--inline{float:right}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice{margin-left:5px;margin-right:auto}.select2-container--default[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--default.select2-container--focus .select2-selection--multiple{border:solid black 1px;outline:0}.select2-container--default.select2-container--disabled .select2-selection--multiple{background-color:#eee;cursor:default}.select2-container--default.select2-container--disabled .select2-selection__choice__remove{display:none}.select2-container--default.select2-container--open.select2-container--above .select2-selection--single,.select2-container--default.select2-container--open.select2-container--above .select2-selection--multiple{border-top-left-radius:0;border-top-right-radius:0}.select2-container--default.select2-container--open.select2-container--below .select2-selection--single,.select2-container--default.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--default .select2-search--dropdown .select2-search__field{border:1px solid #aaa}.select2-container--default .select2-search--inline .select2-search__field{background:transparent;border:none;outline:0;box-shadow:none;-webkit-appearance:textfield}.select2-container--default .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--default .select2-results__option[role=group]{padding:0}.select2-container--default .select2-results__option[aria-disabled=true]{color:#999}.select2-container--default .select2-results__option[aria-selected=true]{background-color:#ddd}.select2-container--default .select2-results__option .select2-results__option{padding-left:1em}.select2-container--default .select2-results__option .select2-results__option .select2-results__group{padding-left:0}.select2-container--default .select2-results__option .select2-results__option .select2-results__option{margin-left:-1em;padding-left:2em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-2em;padding-left:3em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-3em;padding-left:4em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-4em;padding-left:5em}.select2-container--default .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option .select2-results__option{margin-left:-5em;padding-left:6em}.select2-container--default .select2-results__option--highlighted[aria-selected]{background-color:#5897fb;color:white}.select2-container--default .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic .select2-selection--single{background-color:#f7f7f7;border:1px solid #aaa;border-radius:4px;outline:0;background-image:-webkit-linear-gradient(top, #fff 50%, #eee 100%);background-image:-o-linear-gradient(top, #fff 50%, #eee 100%);background-image:linear-gradient(to bottom, #fff 50%, #eee 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic .select2-selection--single:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--single .select2-selection__rendered{color:#444;line-height:28px}.select2-container--classic .select2-selection--single .select2-selection__clear{cursor:pointer;float:right;font-weight:bold;margin-right:10px}.select2-container--classic .select2-selection--single .select2-selection__placeholder{color:#999}.select2-container--classic .select2-selection--single .select2-selection__arrow{background-color:#ddd;border:none;border-left:1px solid #aaa;border-top-right-radius:4px;border-bottom-right-radius:4px;height:26px;position:absolute;top:1px;right:1px;width:20px;background-image:-webkit-linear-gradient(top, #eee 50%, #ccc 100%);background-image:-o-linear-gradient(top, #eee 50%, #ccc 100%);background-image:linear-gradient(to bottom, #eee 50%, #ccc 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFCCCCCC', GradientType=0)}.select2-container--classic .select2-selection--single .select2-selection__arrow b{border-color:#888 transparent transparent transparent;border-style:solid;border-width:5px 4px 0 4px;height:0;left:50%;margin-left:-4px;margin-top:-2px;position:absolute;top:50%;width:0}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__clear{float:left}.select2-container--classic[dir="rtl"] .select2-selection--single .select2-selection__arrow{border:none;border-right:1px solid #aaa;border-radius:0;border-top-left-radius:4px;border-bottom-left-radius:4px;left:1px;right:auto}.select2-container--classic.select2-container--open .select2-selection--single{border:1px solid #5897fb}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow{background:transparent;border:none}.select2-container--classic.select2-container--open .select2-selection--single .select2-selection__arrow b{border-color:transparent transparent #888 transparent;border-width:0 4px 5px 4px}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--single{border-top:none;border-top-left-radius:0;border-top-right-radius:0;background-image:-webkit-linear-gradient(top, #fff 0%, #eee 50%);background-image:-o-linear-gradient(top, #fff 0%, #eee 50%);background-image:linear-gradient(to bottom, #fff 0%, #eee 50%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFFFFFFF', endColorstr='#FFEEEEEE', GradientType=0)}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--single{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0;background-image:-webkit-linear-gradient(top, #eee 50%, #fff 100%);background-image:-o-linear-gradient(top, #eee 50%, #fff 100%);background-image:linear-gradient(to bottom, #eee 50%, #fff 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#FFEEEEEE', endColorstr='#FFFFFFFF', GradientType=0)}.select2-container--classic .select2-selection--multiple{background-color:white;border:1px solid #aaa;border-radius:4px;cursor:text;outline:0}.select2-container--classic .select2-selection--multiple:focus{border:1px solid #5897fb}.select2-container--classic .select2-selection--multiple .select2-selection__rendered{list-style:none;margin:0;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__clear{display:none}.select2-container--classic .select2-selection--multiple .select2-selection__choice{background-color:#e4e4e4;border:1px solid #aaa;border-radius:4px;cursor:default;float:left;margin-right:5px;margin-top:5px;padding:0 5px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove{color:#888;cursor:pointer;display:inline-block;font-weight:bold;margin-right:2px}.select2-container--classic .select2-selection--multiple .select2-selection__choice__remove:hover{color:#555}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice{float:right;margin-left:5px;margin-right:auto}.select2-container--classic[dir="rtl"] .select2-selection--multiple .select2-selection__choice__remove{margin-left:2px;margin-right:auto}.select2-container--classic.select2-container--open .select2-selection--multiple{border:1px solid #5897fb}.select2-container--classic.select2-container--open.select2-container--above .select2-selection--multiple{border-top:none;border-top-left-radius:0;border-top-right-radius:0}.select2-container--classic.select2-container--open.select2-container--below .select2-selection--multiple{border-bottom:none;border-bottom-left-radius:0;border-bottom-right-radius:0}.select2-container--classic .select2-search--dropdown .select2-search__field{border:1px solid #aaa;outline:0}.select2-container--classic .select2-search--inline .select2-search__field{outline:0;box-shadow:none}.select2-container--classic .select2-dropdown{background-color:#fff;border:1px solid transparent}.select2-container--classic .select2-dropdown--above{border-bottom:none}.select2-container--classic .select2-dropdown--below{border-top:none}.select2-container--classic .select2-results>.select2-results__options{max-height:200px;overflow-y:auto}.select2-container--classic .select2-results__option[role=group]{padding:0}.select2-container--classic .select2-results__option[aria-disabled=true]{color:grey}.select2-container--classic .select2-results__option--highlighted[aria-selected]{background-color:#3875d7;color:#fff}.select2-container--classic .select2-results__group{cursor:default;display:block;padding:6px}.select2-container--classic.select2-container--open .select2-dropdown{border-color:#5897fb} diff --git a/css/style-compat.css b/css/style-compat.css deleted file mode 100644 index 2617a68..0000000 --- a/css/style-compat.css +++ /dev/null @@ -1,74 +0,0 @@ -#app-navigation:not(.vue) > ul { - position: relative; - height: 100%; - width: 100%; - overflow-x: hidden; - overflow-y: auto; - box-sizing: border-box; - display: flex; - flex-direction: column; - padding: calc(var(--default-grid-baseline) * 2); -} - -#app-navigation:not(.vue) > ul > li, -#app-navigation:not(.vue) > ul > li > ul > li { - position: relative; - box-sizing: border-box; -} - -#app-navigation:not(.vue) > ul > li { - display: inline-flex; - flex-wrap: wrap; - order: 1; - flex-shrink: 0; - margin: 0; - margin-bottom: 3px; - width: 100%; - border-radius: var(--border-radius-pill); -} - -#app-navigation:not(.vue) > ul > li.active, -#app-navigation:not(.vue) > ul > li.active > a, -#app-navigation:not(.vue) > ul > li a:active, -#app-navigation:not(.vue) > ul > li a:active > a, -#app-navigation:not(.vue) > ul > li a.selected, -#app-navigation:not(.vue) > ul > li a.selected > a, -#app-navigation:not(.vue) > ul > li a.active, -#app-navigation:not(.vue) > ul > li a.active > a { - background-color: var(--color-primary-light); -} - -#app-navigation:not(.vue) > ul > li > a, -#app-navigation:not(.vue) > ul > li > ul > li > a { - background-size: 16px 16px; - background-position: 14px center; - background-repeat: no-repeat; - display: block; - justify-content: space-between; - line-height: 44px; - min-height: 44px; - padding: 0 12px 0 14px; - overflow: hidden; - box-sizing: border-box; - white-space: nowrap; - text-overflow: ellipsis; - border-radius: var(--border-radius-pill); - color: var(--color-main-text); - flex: 1 1 0px; - z-index: 100; -} - -#app-navigation:not(.vue) > ul > li a:hover, -#app-navigation:not(.vue) > ul > li a:hover > a, -#app-navigation:not(.vue) > ul > li a:focus, -#app-navigation:not(.vue) > ul > li a:focus > a { - background-color: var(--color-background-hover); -} - -#app-navigation:not(.vue) > ul > li > a:first-child img, -#app-navigation:not(.vue) > ul > li > ul > li > a:first-child img { - margin-right: 11px; - width: 16px; - height: 16px; - filter: var(--background-invert-if-dark); -} diff --git a/css/style.css b/css/style.css deleted file mode 100644 index 5fe5fb6..0000000 --- a/css/style.css +++ /dev/null @@ -1,583 +0,0 @@ -#hello { - color: red; -} -#work-input { - width: 100%; - /* flex: 1 1 auto; */ - height: 65px; - flex: 1 1 auto; - font-size: 22px; - padding: 0px 5px 0px 20px; -} -#work-input-container { - width: 100%; - flex: 1 1 auto; -} -#top-work-bar { - width: 100%; - display: flex; - flex-direction: row; - align-items: center; -} -#top-work-bar-right { - /* width: 100%; */ - /* background-color: aqua; */ - /* min-width:240px; */ - display: flex; - align-items: center; - flex-shrink: 0; -} -#start-tracking { - display: flex; - align-items: center; - justify-content: center; - width: 36px; - height: 36px; - padding: 0; - flex-shrink: 0; -} -#start-tracking .my-icon { - position: static; - margin: 0; - top: auto; - left: auto; -} - -#app { - width: 100%; -} - -#app-content-wrapper { - width: 100%; - display:block; -} - - -.play-button { - - background-image: url(../img/play-button.svg); - background-position: 0px 0px; -} -.stop-button { - background-image: url(../img/stop-button.svg); - background-position: 0px 0px; -} -.clearfix:after { content: "\00A0"; display: block; clear: both; visibility: hidden; line-height: 0; height: 0;} -.clearfix{ display: inline-block;} -html[xmlns] .clearfix { display: block;} -* html .clearfix{ height: 1%;} -.clearfix {display: block} - -#timetracker-content { - width: 100%; - display:block; - /*background-color: rgb(250, 251, 252);*/ -} -#timer { - /* min-width: 200px; */ - height: 40px; - font-size: 22px; - padding: 25px; - text-align:right; -} -.day-work-intervals{ - - margin-bottom: 30px; - box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1); - - /*background-color: white;*/ - /*min-width: 100%;*/ -} -.day-list-item{ - -} -.day-name { - - font-size: 18px; - font-weight: 400; - padding: 10px; -} -.wi-child { - /*background-color: rgb(250, 251, 252);*/ - background-color: var(--color-background-dark); - padding-left: 25px; - padding-right: 25px; -} -.wi-child-element { - display: flex; - border-bottom: #eee solid 1px; - flex-direction:row; -} -.wi-child-duration { - padding: 10px; - min-width: 150px; - text-align: right; -} -.wi-child-name { - padding: 10px; - width: 100%; -} -.wi-child-hours { - /* font-size: 18px; - font-weight: 400; */ - padding: 10px; - min-width: 150px; - cursor: pointer; -} - -.work-item { - -} -.work-item-element { - display: flex; - flex-direction: row; - box-shadow: inset 0 -1px 0 0 #e8e8e8; - /*background-color: white;*/ - line-height: 60px; - padding-right: 25px; -} -.wi-len { - min-width: 20px; - padding-left: 5px; - border-color: #aaa; - border-width: 1px; - border-style: solid; - line-height: 28px; - margin: 15px; - border-radius: 15px; -} -.wi-len-empty { - min-width: 20px; - padding-left: 5px; - margin: 15px; - line-height: 28px; -} -.wi-name { - width: 100%; - font-size: 16px; -} -.wi-duration { - font-size: 20px; - min-width: 150px; - text-align: right; -} -.nav-icon-recent { - background-image: var(--icon-files-recent-000); -} -.controls { - display: flex; - align-items: center; -} -.client-button { - display:flex; - color: #595959; - /*background-color: #e6e6e6;*/ - font-size: 11px; - padding: 7px 10px; - margin: 0 12px 12px 0; -} - -.client-edit{ - padding:0px 10px; -} -.client-delete{ - padding:0px 10px; -} - -.clickable:hover{ - color: var(--color-main-text); - opacity: 1; -} -.clickable { - cursor: pointer; - color: var(--color-main-text); - opacity: 0.57; -} -.ui-dialog { z-index: 1000 !important ;} -#timetracker-clients { - width: 100%; - /* display:block; */ - /*background-color: rgb(250, 251, 252);*/ - display: inline-block; - margin: 40px; - padding: 20px; -} -.client-button{ - width: min-content; -} -.clients-list{ - display: flex; - margin: 40px; - flex-wrap: wrap; -} -#timetracker-projects{ - width: 100%; - /* display:block; */ - /*background-color: rgb(250, 251, 252);*/ - display: inline-block; - margin: 40px; - padding: 20px; -} - -.project-button{ - display:flex; -} - -.project-name{ - flex:0.3; -} -button.redButton { - background-color: red; -} -.king-table-region .pagination-bar { - height: 50px; - margin: 20px 0px 20px 0px; - padding: 10px; - text-align: right; - /*background-color: #eee;*/ -} -.projects{ - margin-top: 50px; -} -.king-table-head { - color: #aaa; -} -td.deleteBtn { - width: 10px; -} -td.ε_row { - width: 40px; -} -#client-select{ - -} -.select2-container { - margin: 0px 3px 3px 0; - - -} -.select2-container .select2-choice { - min-height: 33px; - height: 33px; - margin-top:0px; -} -.page-title { - font-size: 32px; -} -#timetracker-tags { - width: 100%; - /* display: block; */ - /*background-color: rgb(250, 251, 252);*/ - display: inline-block; - margin: 40px; - padding: 20px; -} -.tag-button { - display:flex; - color: #595959; - /*background-color: #e6e6e6;*/ - font-size: 11px; - padding: 7px 10px; - margin: 0 12px 12px 0; -} - -.tag-edit{ - padding:0px 10px; -} -.tag-delete{ - padding:0px 10px; -} -.tags-list{ - display: flex; - margin: 40px; - flex-wrap: wrap; -} -#timetracker-goals { - width: 100%; - /* display: block; */ - /*background-color: rgb(250, 251, 252);*/ - display: inline-block; - margin: 40px; - padding: 20px; -} -.set-project{ - line-height: 32px; - min-width: 200px; - padding-left: 10px; -} -/* -.set-tag{ - line-height: 32px; - font-size: 22px; - padding-left: 10px; -}*/ - -.select2-container.set-project .select2-default { - margin: 0px; - border: 0px; - font-size: 22px; - /*width:40px;*/ - - /*background-color: rgb(250, 251, 252);*/ -} -/* -.select2-container.set-tag .select2-default { - margin: 0px; - border: 0px; - background-color: rgb(250, 251, 252); -}*/ -.select2-search-choice-close { - display: block; -} -.wi-trash { - line-height: 33px; - font-size: 15px; - display: none; -} -.wi-child-element:hover .wi-trash { - display: block; -} -.wi-play { - line-height: 40px; - font-size: 15px; - display: none; -} -.wi-child-element:hover .wi-play { - display: block; -} -.wi-play-space { - min-width: 15px; -} -.set-tag { - min-width: 200px; -} -#report { - margin-top:30px; -} -#timetracker-dashboard { - width: 100%; - /* display: block; */ - /*background-color: rgb(250, 251, 252);*/ - display: inline-block; - margin: 40px; - padding: 20px; -} -#dashboard{ - max-width: 600px; -} -#dashboard h1{ - margin-top:10px; - font-size: 20px; -} -.nav-icon-projects { - - background-image: var(--icon-folder-000); - } -.nav-icon-timer { - - background-image: var(--icon-play-000); - } -.nav-icon-clients { - background-image: var(--icon-contacts-000); -} -.nav-icon-tags { - background-image: var(--icon-tag-000); -} -.nav-icon-reports { - background-image: var(--icon-edit-000); -} -.nav-icon-dashboard { - background-image: var(--icon-desktop-000); -} -.nav-icon-goals { - background-image: var(--icon-monitoring-000); -} -/* .ui-button.primary { - background-color: red; -} -.ui-button.greenButton { - background-color: green; -} */ -#projects { - margin-top: 30px; -} -#projects .tabulator-cell{ - cursor: pointer; -} -.my-icon { - display: inline-block; - vertical-align: middle; - text-indent: -99999px; - overflow: hidden; - background-repeat: no-repeat; - position: absolute; - top: 50%; - left: 50%; - margin-top: -8px; - margin-left: -8px; - width: 16px; - height: 16px; -} -#tags { - margin-top: 30px; -} -#clients { - margin-top: 30px; -} -#manual-entry-button { - float:right; -} - - -#form-manual-entry label {display: block;} -#hours-manual-entry{ - width: 240px; -} -.daterangepicker { - background-color: var(--color-main-background); -} -.daterangepicker .calendar-table { - border: 1px solid var(--color-main-background); - border-radius: 4px; - background-color: var(--color-main-background); -} -.daterangepicker select.hourselect, .daterangepicker select.minuteselect, .daterangepicker select.secondselect, .daterangepicker select.ampmselect { - width: 50px; - margin: 0 auto; - background:var(--color-background-dark); - border: 1px solid var(--color-background-dark); - padding: 2px; - outline: 0; - font-size: 12px; -} - -.daterangepicker td.off, .daterangepicker td.off.in-range, .daterangepicker td.off.start-date, .daterangepicker td.off.end-date { - background-color:var(--color-main-background); - border-color: transparent; - color: var(--color-background-darker); -} - -.daterangepicker td.available:hover, .daterangepicker th.available:hover { - background-color: var(--color-background-darker); - border-color: transparent; - color: inherit; -} -.daterangepicker .ranges li:hover { - background-color: var(--color-background-darker); -} - -.tabulator .tabulator-tableHolder .tabulator-table { - background-color:var(--color-main-background); - color:var(--color-main-text); -} -.tabulator-row { - background-color:var(--color-main-background); -} -.tabulator-row.tabulator-row-even { - background-color:var(--color-background-dark); -} -.tabulator-row.tabulator-selectable:hover { - background-color:var(--color-background-darker); -} - -.tabulator .tabulator-header { - background-color: var(--color-background-dark); - color: var(--color-text-lighter); -} -.tabulator .tabulator-header .tabulator-col { - background-color: var(--color-background-dark); -} - -.ui-widget-header { - background: var(--color-background-dark); - color: var(--color-text-lighter); -} -.select2-search { background-color: var(--color-main-background); color: var(--color-text-darker)} -.select2-search input { background-color: var(--color-main-background); color: var(--color-text-darker)} -.select2-results { background-color: var(--color-main-background); color: var(--color-text-darker)} -.select2-selection { background-color: var(--color-main-background); color: var(--color-text-darker)} -.select2-container--default .select2-selection--single { - background-color: var(--color-main-background); - color: var(--color-text-darker) -} -.select2-container--default .select2-selection--single .select2-selection__rendered{ - line-height: 26px; - background-color: var(--color-main-background); - color: var(--color-text-darker) -} - -.select2-container--default .select2-selection--single .select2-selection__placeholder{ - background-color: var(--color-main-background); - color: var(--color-text-lighter) -} -.select2-container--default .select2-selection--multiple .select2-selection__choice { - background-color: var(--color-main-background); - color: var(--color-text-lighter); -} -.select2-container--default .select2-selection--multiple { - background-color: var(--color-main-background); -} -.select2-container--default.select2-container--focus .select2-selection--multiple { - border: solid var(--color-text-lighter) 1px; -} - -#report-range{ - /*var(--color-background-dark);*/ - -} -.select2-dropdown { - background-color: var(--color-background-dark); -} -.ui-button{ - background-color: var(--color-main-background); - color: var(--color-text-normal); -} -.ui-widget-content { - background-color: var(--color-main-background); - color: var(--color-text-normal); -} -.select-project-color { - display: inline-block; - width: 9px; - height: 5px; - margin: 3px; - border-radius: 100%; -} - -.select-project { - /*font-size: 24px;*/ -} -.tags-select { - width:200px; -} -.project-select { - width:200px; -} -@media screen and (max-width: 700px) { - .wi-child-element { - display: inline-flex; - flex-direction:column; - width: 100%; - } - .wi-trash { - display: inline; - } - .wi-child-duration { - text-align: left; - } - .wi-child{ - border-bottom: 2px var(--color-background-darker) solid; - } - .tags-select { - width:auto; - } - .project-select { - width:auto; - } - .wi-play{ - display:table; - margin: 0 auto; - } - - -} \ No newline at end of file diff --git a/css/tabulator.css b/css/tabulator.css deleted file mode 100644 index 43dc1f3..0000000 --- a/css/tabulator.css +++ /dev/null @@ -1,769 +0,0 @@ -/* Tabulator v4.1.5 (c) Oliver Folkerd */ -.tabulator { - position: relative; - border: 1px solid #999; - background-color: #888; - font-size: 14px; - text-align: left; - overflow: hidden; - -ms-transform: translatez(0); - transform: translatez(0); -} - -.tabulator[tabulator-layout="fitDataFill"] .tabulator-tableHolder .tabulator-table { - min-width: 100%; -} - -.tabulator.tabulator-block-select { - -webkit-user-select: none; - -moz-user-select: none; - -ms-user-select: none; - user-select: none; -} - -.tabulator .tabulator-header { - position: relative; - box-sizing: border-box; - width: 100%; - border-bottom: 1px solid #999; - background-color: #e6e6e6; - color: #555; - font-weight: bold; - white-space: nowrap; - overflow: hidden; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; -} - -.tabulator .tabulator-header .tabulator-col { - display: inline-block; - position: relative; - box-sizing: border-box; - border-right: 1px solid #aaa; - background: #e6e6e6; - text-align: left; - vertical-align: bottom; - overflow: hidden; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-moving { - position: absolute; - border: 1px solid #999; - background: #cdcdcd; - pointer-events: none; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-col-content { - box-sizing: border-box; - position: relative; - padding: 4px; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title { - box-sizing: border-box; - width: 100%; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - vertical-align: bottom; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-col-title .tabulator-title-editor { - box-sizing: border-box; - width: 100%; - border: 1px solid #999; - padding: 1px; - background: #fff; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-col-content .tabulator-arrow { - display: inline-block; - position: absolute; - top: 9px; - right: 8px; - width: 0; - height: 0; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-bottom: 6px solid #bbb; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols { - position: relative; - display: -ms-flexbox; - display: flex; - border-top: 1px solid #aaa; - overflow: hidden; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-col-group .tabulator-col-group-cols .tabulator-col:last-child { - margin-right: -1px; -} - -.tabulator .tabulator-header .tabulator-col:first-child .tabulator-col-resize-handle.prev { - display: none; -} - -.tabulator .tabulator-header .tabulator-col.ui-sortable-helper { - position: absolute; - background-color: #e6e6e6 !important; - border: 1px solid #aaa; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-header-filter { - position: relative; - box-sizing: border-box; - margin-top: 2px; - width: 100%; - text-align: center; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-header-filter textarea { - height: auto !important; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-header-filter svg { - margin-top: 3px; -} - -.tabulator .tabulator-header .tabulator-col .tabulator-header-filter input::-ms-clear { - width: 0; - height: 0; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-sortable .tabulator-col-title { - padding-right: 25px; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-sortable:hover { - cursor: pointer; - background-color: #cdcdcd; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="none"] .tabulator-col-content .tabulator-arrow { - border-top: none; - border-bottom: 6px solid #bbb; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="asc"] .tabulator-col-content .tabulator-arrow { - border-top: none; - border-bottom: 6px solid #666; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-sortable[aria-sort="desc"] .tabulator-col-content .tabulator-arrow { - border-top: 6px solid #666; - border-bottom: none; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical .tabulator-col-content .tabulator-col-title { - -webkit-writing-mode: vertical-rl; - -ms-writing-mode: tb-rl; - writing-mode: vertical-rl; - text-orientation: mixed; - display: -ms-flexbox; - display: flex; - -ms-flex-align: center; - align-items: center; - -ms-flex-pack: center; - justify-content: center; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-col-vertical-flip .tabulator-col-title { - -ms-transform: rotate(180deg); - transform: rotate(180deg); -} - -.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-col-title { - padding-right: 0; - padding-top: 20px; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable.tabulator-col-vertical-flip .tabulator-col-title { - padding-right: 0; - padding-bottom: 20px; -} - -.tabulator .tabulator-header .tabulator-col.tabulator-col-vertical.tabulator-sortable .tabulator-arrow { - right: calc(50% - 6px); -} - -.tabulator .tabulator-header .tabulator-frozen { - display: inline-block; - position: absolute; - z-index: 10; -} - -.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-left { - border-right: 2px solid #aaa; -} - -.tabulator .tabulator-header .tabulator-frozen.tabulator-frozen-right { - border-left: 2px solid #aaa; -} - -.tabulator .tabulator-header .tabulator-calcs-holder { - box-sizing: border-box; - min-width: 400%; - background: #f3f3f3 !important; - border-top: 1px solid #aaa; - border-bottom: 1px solid #aaa; - overflow: hidden; -} - -.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row { - background: #f3f3f3 !important; -} - -.tabulator .tabulator-header .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle { - display: none; -} - -.tabulator .tabulator-header .tabulator-frozen-rows-holder { - min-width: 400%; -} - -.tabulator .tabulator-header .tabulator-frozen-rows-holder:empty { - display: none; -} - -.tabulator .tabulator-tableHolder { - position: relative; - width: 100%; - white-space: nowrap; - overflow: auto; - -webkit-overflow-scrolling: touch; -} - -.tabulator .tabulator-tableHolder:focus { - outline: none; -} - -.tabulator .tabulator-tableHolder .tabulator-placeholder { - box-sizing: border-box; - display: -ms-flexbox; - display: flex; - -ms-flex-align: center; - align-items: center; - width: 100%; -} - -.tabulator .tabulator-tableHolder .tabulator-placeholder[tabulator-render-mode="virtual"] { - position: absolute; - top: 0; - left: 0; - height: 100%; -} - -.tabulator .tabulator-tableHolder .tabulator-placeholder span { - display: inline-block; - margin: 0 auto; - padding: 10px; - color: #ccc; - font-weight: bold; - font-size: 20px; -} - -.tabulator .tabulator-tableHolder .tabulator-table { - position: relative; - display: inline-block; - background-color: #fff; - white-space: nowrap; - overflow: visible; - color: #333; -} - -.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs { - font-weight: bold; - background: #e2e2e2 !important; -} - -.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-top { - border-bottom: 2px solid #aaa; -} - -.tabulator .tabulator-tableHolder .tabulator-table .tabulator-row.tabulator-calcs.tabulator-calcs-bottom { - border-top: 2px solid #aaa; -} - -.tabulator .tabulator-footer { - padding: 5px 10px; - border-top: 1px solid #999; - background-color: #e6e6e6; - text-align: right; - color: #555; - font-weight: bold; - white-space: nowrap; - -ms-user-select: none; - user-select: none; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; -} - -.tabulator .tabulator-footer .tabulator-calcs-holder { - box-sizing: border-box; - width: calc(100% + 20px); - margin: -5px -10px 5px -10px; - text-align: left; - background: #f3f3f3 !important; - border-bottom: 1px solid #aaa; - border-top: 1px solid #aaa; - overflow: hidden; -} - -.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row { - background: #f3f3f3 !important; -} - -.tabulator .tabulator-footer .tabulator-calcs-holder .tabulator-row .tabulator-col-resize-handle { - display: none; -} - -.tabulator .tabulator-footer .tabulator-calcs-holder:only-child { - margin-bottom: -5px; - border-bottom: none; -} - -.tabulator .tabulator-footer .tabulator-pages { - margin: 0 7px; -} - -.tabulator .tabulator-footer .tabulator-page { - display: inline-block; - margin: 0 2px; - padding: 2px 5px; - border: 1px solid #aaa; - border-radius: 3px; - background: rgba(255, 255, 255, 0.2); - color: #555; - font-family: inherit; - font-weight: inherit; - font-size: inherit; -} - -.tabulator .tabulator-footer .tabulator-page.active { - color: #d00; -} - -.tabulator .tabulator-footer .tabulator-page:disabled { - opacity: .5; -} - -.tabulator .tabulator-footer .tabulator-page:not(.disabled):hover { - cursor: pointer; - background: rgba(0, 0, 0, 0.2); - color: #fff; -} - -.tabulator .tabulator-col-resize-handle { - position: absolute; - right: 0; - top: 0; - bottom: 0; - width: 5px; -} - -.tabulator .tabulator-col-resize-handle.prev { - left: 0; - right: auto; -} - -.tabulator .tabulator-col-resize-handle:hover { - cursor: ew-resize; -} - -.tabulator .tabulator-loader { - position: absolute; - display: -ms-flexbox; - display: flex; - -ms-flex-align: center; - align-items: center; - top: 0; - left: 0; - z-index: 100; - height: 100%; - width: 100%; - background: rgba(0, 0, 0, 0.4); - text-align: center; -} - -.tabulator .tabulator-loader .tabulator-loader-msg { - display: inline-block; - margin: 0 auto; - padding: 10px 20px; - border-radius: 10px; - background: #fff; - font-weight: bold; - font-size: 16px; -} - -.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-loading { - border: 4px solid #333; - color: #000; -} - -.tabulator .tabulator-loader .tabulator-loader-msg.tabulator-error { - border: 4px solid #D00; - color: #590000; -} - -.tabulator-row { - position: relative; - box-sizing: border-box; - min-height: 22px; - background-color: #fff; -} - -.tabulator-row.tabulator-row-even { - background-color: #EFEFEF; -} - -.tabulator-row.tabulator-selectable:hover { - background-color: #bbb; - cursor: pointer; -} - -.tabulator-row.tabulator-selected { - background-color: #9ABCEA; -} - -.tabulator-row.tabulator-selected:hover { - background-color: #769BCC; - cursor: pointer; -} - -.tabulator-row.tabulator-row-moving { - border: 1px solid #000; - background: #fff; -} - -.tabulator-row.tabulator-moving { - position: absolute; - border-top: 1px solid #aaa; - border-bottom: 1px solid #aaa; - pointer-events: none; - z-index: 15; -} - -.tabulator-row .tabulator-row-resize-handle { - position: absolute; - right: 0; - bottom: 0; - left: 0; - height: 5px; -} - -.tabulator-row .tabulator-row-resize-handle.prev { - top: 0; - bottom: auto; -} - -.tabulator-row .tabulator-row-resize-handle:hover { - cursor: ns-resize; -} - -.tabulator-row .tabulator-frozen { - display: inline-block; - position: absolute; - background-color: inherit; - z-index: 10; -} - -.tabulator-row .tabulator-frozen.tabulator-frozen-left { - border-right: 2px solid #aaa; -} - -.tabulator-row .tabulator-frozen.tabulator-frozen-right { - border-left: 2px solid #aaa; -} - -.tabulator-row .tabulator-responsive-collapse { - box-sizing: border-box; - padding: 5px; - border-top: 1px solid #aaa; - border-bottom: 1px solid #aaa; -} - -.tabulator-row .tabulator-responsive-collapse:empty { - display: none; -} - -.tabulator-row .tabulator-responsive-collapse table { - font-size: 14px; -} - -.tabulator-row .tabulator-responsive-collapse table tr td { - position: relative; -} - -.tabulator-row .tabulator-responsive-collapse table tr td:first-of-type { - padding-right: 10px; -} - -.tabulator-row .tabulator-cell { - display: inline-block; - position: relative; - box-sizing: border-box; - padding: 4px; - border-right: 1px solid #aaa; - vertical-align: middle; - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; -} - -.tabulator-row .tabulator-cell.tabulator-editing { - border: 1px solid #1D68CD; - padding: 0; -} - -.tabulator-row .tabulator-cell.tabulator-editing input, .tabulator-row .tabulator-cell.tabulator-editing select { - border: 1px; - background: transparent; -} - -.tabulator-row .tabulator-cell.tabulator-validation-fail { - border: 1px solid #dd0000; -} - -.tabulator-row .tabulator-cell.tabulator-validation-fail input, .tabulator-row .tabulator-cell.tabulator-validation-fail select { - border: 1px; - background: transparent; - color: #dd0000; -} - -.tabulator-row .tabulator-cell:first-child .tabulator-col-resize-handle.prev { - display: none; -} - -.tabulator-row .tabulator-cell.tabulator-row-handle { - display: -ms-inline-flexbox; - display: inline-flex; - -ms-flex-align: center; - align-items: center; - -ms-flex-pack: center; - justify-content: center; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; -} - -.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box { - width: 80%; -} - -.tabulator-row .tabulator-cell.tabulator-row-handle .tabulator-row-handle-box .tabulator-row-handle-bar { - width: 100%; - height: 3px; - margin-top: 2px; - background: #666; -} - -.tabulator-row .tabulator-cell .tabulator-data-tree-branch { - display: inline-block; - vertical-align: middle; - height: 9px; - width: 7px; - margin-top: -9px; - margin-right: 5px; - border-bottom-left-radius: 1px; - border-left: 2px solid #aaa; - border-bottom: 2px solid #aaa; -} - -.tabulator-row .tabulator-cell .tabulator-data-tree-control { - display: -ms-inline-flexbox; - display: inline-flex; - -ms-flex-pack: center; - justify-content: center; - -ms-flex-align: center; - align-items: center; - vertical-align: middle; - height: 11px; - width: 11px; - margin-right: 5px; - border: 1px solid #333; - border-radius: 2px; - background: rgba(0, 0, 0, 0.1); - overflow: hidden; -} - -.tabulator-row .tabulator-cell .tabulator-data-tree-control:hover { - cursor: pointer; - background: rgba(0, 0, 0, 0.2); -} - -.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse { - display: inline-block; - position: relative; - height: 7px; - width: 1px; - background: transparent; -} - -.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-collapse:after { - position: absolute; - content: ""; - left: -3px; - top: 3px; - height: 1px; - width: 7px; - background: #333; -} - -.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand { - display: inline-block; - position: relative; - height: 7px; - width: 1px; - background: #333; -} - -.tabulator-row .tabulator-cell .tabulator-data-tree-control .tabulator-data-tree-control-expand:after { - position: absolute; - content: ""; - left: -3px; - top: 3px; - height: 1px; - width: 7px; - background: #333; -} - -.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle { - display: -ms-inline-flexbox; - display: inline-flex; - -ms-flex-align: center; - align-items: center; - -ms-flex-pack: center; - justify-content: center; - -moz-user-select: none; - -khtml-user-select: none; - -webkit-user-select: none; - -o-user-select: none; - height: 15px; - width: 15px; - border-radius: 20px; - background: #666; - color: #fff; - font-weight: bold; - font-size: 1.1em; -} - -.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle:hover { - opacity: .7; -} - -.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-close { - display: initial; -} - -.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle.open .tabulator-responsive-collapse-toggle-open { - display: none; -} - -.tabulator-row .tabulator-cell .tabulator-responsive-collapse-toggle .tabulator-responsive-collapse-toggle-close { - display: none; -} - -.tabulator-row.tabulator-group { - box-sizing: border-box; - border-bottom: 1px solid #999; - border-right: 1px solid #aaa; - border-top: 1px solid #999; - padding: 5px; - padding-left: 10px; - background: #ccc; - font-weight: bold; - min-width: 100%; -} - -.tabulator-row.tabulator-group:hover { - cursor: pointer; - background-color: rgba(0, 0, 0, 0.1); -} - -.tabulator-row.tabulator-group.tabulator-group-visible .tabulator-arrow { - margin-right: 10px; - border-left: 6px solid transparent; - border-right: 6px solid transparent; - border-top: 6px solid #666; - border-bottom: 0; -} - -.tabulator-row.tabulator-group.tabulator-group-level-1 .tabulator-arrow { - margin-left: 20px; -} - -.tabulator-row.tabulator-group.tabulator-group-level-2 .tabulator-arrow { - margin-left: 40px; -} - -.tabulator-row.tabulator-group.tabulator-group-level-3 .tabulator-arrow { - margin-left: 60px; -} - -.tabulator-row.tabulator-group.tabulator-group-level-4 .tabulator-arrow { - margin-left: 80px; -} - -.tabulator-row.tabulator-group.tabulator-group-level-5 .tabulator-arrow { - margin-left: 100px; -} - -.tabulator-row.tabulator-group .tabulator-arrow { - display: inline-block; - width: 0; - height: 0; - margin-right: 16px; - border-top: 6px solid transparent; - border-bottom: 6px solid transparent; - border-right: 0; - border-left: 6px solid #666; - vertical-align: middle; -} - -.tabulator-row.tabulator-group span { - margin-left: 10px; - color: #d00; -} - -.tabulator-edit-select-list { - position: absolute; - display: inline-block; - box-sizing: border-box; - max-height: 200px; - background: #fff; - border: 1px solid #aaa; - font-size: 14px; - overflow-y: auto; - -webkit-overflow-scrolling: touch; - z-index: 10000; -} - -.tabulator-edit-select-list .tabulator-edit-select-list-item { - padding: 4px; - color: #333; -} - -.tabulator-edit-select-list .tabulator-edit-select-list-item.active { - color: #fff; - background: #1D68CD; -} - -.tabulator-edit-select-list .tabulator-edit-select-list-item:hover { - cursor: pointer; - color: #fff; - background: #1D68CD; -} - -.tabulator-edit-select-list .tabulator-edit-select-list-group { - border-bottom: 1px solid #aaa; - padding: 4px; - padding-top: 6px; - color: #333; - font-weight: bold; -} diff --git a/img/play-button.svg b/img/play-button.svg deleted file mode 100644 index 218d9a5..0000000 --- a/img/play-button.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/img/stop-button.svg b/img/stop-button.svg deleted file mode 100644 index ffa7b97..0000000 --- a/img/stop-button.svg +++ /dev/null @@ -1 +0,0 @@ - \ No newline at end of file diff --git a/js/package-lock.json b/js/package-lock.json index fed3ef3..90f32d5 100644 --- a/js/package-lock.json +++ b/js/package-lock.json @@ -10,17 +10,13 @@ "license": "ISC", "dependencies": { "@nextcloud/auth": "^2.6.0", + "@nextcloud/axios": "^2.6.0", + "@nextcloud/dialogs": "^7.4.0", "@nextcloud/router": "^3.1.0", "@nextcloud/vue": "^9.8.2", - "chart.js": "^2.9.4", - "daterangepicker": "^3.1.0", - "jquery": "^3.5.1", - "jquery-migrate": "^3.3.2", - "jqueryui": "^1.11.1", - "moment": "^2.29.4", - "select2": "^4.0.13", - "tabulator-tables": "^4.9.3", + "chart.js": "^4.4.9", "vue": "^3.5.39", + "vue-chartjs": "^5.3.2", "vue-router": "^4.6.4" }, "devDependencies": { @@ -156,7 +152,6 @@ "resolved": "https://registry.npmjs.org/@buttercup/fetch/-/fetch-0.2.1.tgz", "integrity": "sha512-sCgECOx8wiqY8NN1xN22BqqKzXYIG2AicNLlakOAI4f0WgyLVUbAigMf8CZhBtJxdudTcB1gD5lciqi44jwJvg==", "license": "MIT", - "optional": true, "optionalDependencies": { "node-fetch": "^3.3.0" } @@ -287,6 +282,18 @@ "@jridgewell/sourcemap-codec": "^1.4.14" } }, + "node_modules/@kurkle/color": { + "version": "0.3.4", + "resolved": "https://registry.npmjs.org/@kurkle/color/-/color-0.3.4.tgz", + "integrity": "sha512-M5UknZPHRu3DEDWoipU6sE8PdkZ6Z/S+v4dD+Ke8IaNlpdSQah50lz1KtcFBa2vsdOnwbbnxJwVM4wty6udA5w==", + "license": "MIT" + }, + "node_modules/@mdi/js": { + "version": "7.4.47", + "resolved": "https://registry.npmjs.org/@mdi/js/-/js-7.4.47.tgz", + "integrity": "sha512-KPnNOtm5i2pMabqZxpUz7iQf+mfrYZyKCZ8QNz85czgEt7cuHcGorWfdzUMWYA0SD+a6Hn4FmJ+YhzzzjkTZrQ==", + "license": "Apache-2.0" + }, "node_modules/@nextcloud/auth": { "version": "2.6.0", "resolved": "https://registry.npmjs.org/@nextcloud/auth/-/auth-2.6.0.tgz", @@ -349,6 +356,35 @@ "node": "^20.0.0 || ^22.0.0 || ^24.0.0" } }, + "node_modules/@nextcloud/dialogs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/@nextcloud/dialogs/-/dialogs-7.4.0.tgz", + "integrity": "sha512-XAkRls7T1xIxH+E7ArW5+gY0CrqebT+3Pxo30u7XBc21UNgc8vhl4mv5SRiDe9OgSK6/QI0bPNMvCasSaSSVpA==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@mdi/js": "^7.4.47", + "@nextcloud/auth": "^2.6.0", + "@nextcloud/axios": "^2.6.0", + "@nextcloud/browser-storage": "^0.5.0", + "@nextcloud/event-bus": "^3.3.3", + "@nextcloud/files": "^4.0.0", + "@nextcloud/initial-state": "^3.0.0", + "@nextcloud/l10n": "^3.4.1", + "@nextcloud/paths": "^3.1.0", + "@nextcloud/router": "^3.1.0", + "@nextcloud/sharing": "^0.4.0", + "@nextcloud/vue": "^9.8.0", + "@types/toastify-js": "^1.12.4", + "@vueuse/core": "^14.3.0", + "p-queue": "^9.1.2", + "toastify-js": "^1.12.0", + "vue": "^3.5.34", + "webdav": "^5.10.0" + }, + "engines": { + "node": "^20 || ^22 || ^24" + } + }, "node_modules/@nextcloud/event-bus": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/@nextcloud/event-bus/-/event-bus-3.3.3.tgz", @@ -363,6 +399,27 @@ } }, "node_modules/@nextcloud/files": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/@nextcloud/files/-/files-4.0.0.tgz", + "integrity": "sha512-TmecnZIS+PGWGtRh7RpGEboCT4K6iTbHULUcfR6hs3eEzjDVsCc1Ldf8popGY/70lbpdlfYle8xbXnPIo3qaXA==", + "license": "AGPL-3.0-or-later", + "dependencies": { + "@nextcloud/auth": "^2.5.3", + "@nextcloud/capabilities": "^1.2.1", + "@nextcloud/l10n": "^3.4.1", + "@nextcloud/logger": "^3.0.3", + "@nextcloud/paths": "^3.0.0", + "@nextcloud/router": "^3.1.0", + "@nextcloud/sharing": "^0.3.0", + "is-svg": "^6.1.0", + "typescript-event-target": "^1.1.2", + "webdav": "^5.9.0" + }, + "engines": { + "node": "^24.0.0" + } + }, + "node_modules/@nextcloud/files/node_modules/@nextcloud/files": { "version": "3.12.2", "resolved": "https://registry.npmjs.org/@nextcloud/files/-/files-3.12.2.tgz", "integrity": "sha512-vBo8tf3Xh6efiF8CrEo3pKj9AtvAF6RdDGO1XKL65IxV8+UUd9Uxl2lUExHlzoDRRczCqfGfaWfRRaFhYqce5Q==", @@ -390,7 +447,6 @@ "resolved": "https://registry.npmjs.org/@nextcloud/sharing/-/sharing-0.3.0.tgz", "integrity": "sha512-kV7qeUZvd1fTKeFyH+W5Qq5rNOqG9rLATZM3U9MBxWXHJs3OxMqYQb8UQ3NYONzsX3zDGJmdQECIGHm1ei2sCA==", "license": "GPL-3.0-or-later", - "optional": true, "dependencies": { "@nextcloud/initial-state": "^3.0.0", "is-svg": "^6.1.0" @@ -444,7 +500,6 @@ "resolved": "https://registry.npmjs.org/@nextcloud/paths/-/paths-3.1.0.tgz", "integrity": "sha512-vtFYA/kthaUDzu6KejTOL1OwnOy7/yynq5zdB/UBpYacAWjUX5Ddh4OMWx3rEavkBJ9/QGhrFryNJLjNfe8OQA==", "license": "GPL-3.0-or-later", - "optional": true, "engines": { "node": "^20.0.0 || ^22.0.0 || ^24.0.0" } @@ -624,8 +679,7 @@ "url": "https://github.com/sponsors/nodable" } ], - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/@tokenizer/token": { "version": "0.3.0", @@ -731,6 +785,12 @@ "integrity": "sha512-TC0dmN0K8YcWEAEfiPi5gJP14eJe30TTGjkvek3iM/1NdHHsdCA/Td6GvNndMOo/iSnIsZ4HuuhrYPDAmbxzww==", "license": "MIT" }, + "node_modules/@types/toastify-js": { + "version": "1.12.4", + "resolved": "https://registry.npmjs.org/@types/toastify-js/-/toastify-js-1.12.4.tgz", + "integrity": "sha512-zfZHU4tKffPCnZRe7pjv/eFKzTVHozKewFCKaCjZ4gFinKgJRz/t0bkZiMCXJxPhv/ZoeDGNOeRD09R0kQZ/nw==", + "license": "MIT" + }, "node_modules/@types/trusted-types": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", @@ -1332,8 +1392,7 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/ast-kit": { "version": "2.2.0", @@ -1400,15 +1459,13 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/base-64": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/base-64/-/base-64-1.0.0.tgz", "integrity": "sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/baseline-browser-mapping": { "version": "2.10.43", @@ -1453,7 +1510,6 @@ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.2.tgz", "integrity": "sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==", "license": "MIT", - "optional": true, "dependencies": { "balanced-match": "^1.0.0" } @@ -1503,8 +1559,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/byte-length/-/byte-length-1.0.2.tgz", "integrity": "sha512-ovBpjmsgd/teRmgcPh23d4gJvxDoXtAzEL9xTfMU8Yc2kqCDb7L9jAG0XHl1nzuGl+h3ebCIF1i62UFyA9V/2Q==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/call-bind-apply-helpers": { "version": "1.0.2", @@ -1619,38 +1674,20 @@ "resolved": "https://registry.npmjs.org/charenc/-/charenc-0.0.2.tgz", "integrity": "sha512-yrLQ/yVUFXkzg7EDQsPieE/53+0RlaWTs+wBrvW36cyilJ2SaDWfl4Yj7MtLTXleV9uEKefbAGUPv2/iWSooRA==", "license": "BSD-3-Clause", - "optional": true, "engines": { "node": "*" } }, "node_modules/chart.js": { - "version": "2.9.4", - "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-2.9.4.tgz", - "integrity": "sha512-B07aAzxcrikjAPyV+01j7BmOpxtQETxTSlQ26BEYJ+3iUkbNKaOJ/nDbT6JjyqYxseM0ON12COHYdU2cTIjC7A==", - "license": "MIT", - "dependencies": { - "chartjs-color": "^2.1.0", - "moment": "^2.10.2" - } - }, - "node_modules/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==", - "license": "MIT", - "dependencies": { - "chartjs-color-string": "^0.6.0", - "color-convert": "^1.9.3" - } - }, - "node_modules/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==", + "version": "4.5.1", + "resolved": "https://registry.npmjs.org/chart.js/-/chart.js-4.5.1.tgz", + "integrity": "sha512-GIjfiT9dbmHRiYi6Nl2yFCq7kkwdkp1W/lp2J99rX0yo9tgJGn3lKQATztIjb5tVtevcBtIdICNWqlq5+E8/Pw==", "license": "MIT", "dependencies": { - "color-name": "^1.0.0" + "@kurkle/color": "^0.3.0" + }, + "engines": { + "pnpm": ">=8" } }, "node_modules/chokidar": { @@ -1702,25 +1739,11 @@ "node": ">=6" } }, - "node_modules/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==", - "license": "MIT", - "dependencies": { - "color-name": "1.1.3" - } - }, - "node_modules/color-convert/node_modules/color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", - "license": "MIT" - }, "node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true, "license": "MIT" }, "node_modules/colorette": { @@ -1796,7 +1819,6 @@ "resolved": "https://registry.npmjs.org/crypt/-/crypt-0.0.2.tgz", "integrity": "sha512-mCxBlsHFYh9C+HVpiEacem8FEBnMXgU9gy4zmNC+SXAZNB/1idgp/aulFJ4FgCi7GPEVbfyng092GqL2k2rmow==", "license": "BSD-3-Clause", - "optional": true, "engines": { "node": "*" } @@ -1854,7 +1876,6 @@ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz", "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==", "license": "MIT", - "optional": true, "engines": { "node": ">= 12" } @@ -1869,16 +1890,6 @@ "url": "https://github.com/sponsors/kossnocorp" } }, - "node_modules/daterangepicker": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/daterangepicker/-/daterangepicker-3.1.0.tgz", - "integrity": "sha512-DxWXvvPq4srWLCqFugqSV+6CBt/CvQ0dnpXhQ3gl0autcIDAruG1PuGG3gC7yPRNytAD1oU1AcUOzaYhOawhTw==", - "license": "MIT", - "dependencies": { - "jquery": ">=1.10", - "moment": "^2.9.0" - } - }, "node_modules/debounce": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/debounce/-/debounce-3.0.0.tgz", @@ -2257,7 +2268,6 @@ } ], "license": "MIT", - "optional": true, "dependencies": { "path-expression-matcher": "^1.6.2", "xml-naming": "^0.3.0" @@ -2274,7 +2284,6 @@ } ], "license": "MIT", - "optional": true, "dependencies": { "@nodable/entities": "^2.2.0", "fast-xml-builder": "^1.2.0", @@ -2329,7 +2338,6 @@ } ], "license": "MIT", - "optional": true, "dependencies": { "node-domexception": "^1.0.0", "web-streams-polyfill": "^3.0.3" @@ -2461,7 +2469,6 @@ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==", "license": "MIT", - "optional": true, "dependencies": { "fetch-blob": "^3.1.2" }, @@ -2678,8 +2685,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/hot-patcher/-/hot-patcher-2.0.1.tgz", "integrity": "sha512-ECg1JFG0YzehicQaogenlcs2qg6WsXQsxtnbr1i696u5tLUjtJdQAh0u2g0Q5YV45f263Ta1GnUJsc8WIfJf4Q==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/https-proxy-agent": { "version": "5.0.1", @@ -2783,8 +2789,7 @@ "version": "1.1.6", "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/is-core-module": { "version": "2.16.2", @@ -2872,8 +2877,7 @@ "url": "https://github.com/sponsors/NaturalIntelligence" } ], - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", @@ -2923,27 +2927,6 @@ "url": "https://github.com/chalk/supports-color?sponsor=1" } }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "license": "MIT" - }, - "node_modules/jquery-migrate": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/jquery-migrate/-/jquery-migrate-3.6.0.tgz", - "integrity": "sha512-2k3GMQXXEellCOkj8tczgCd/Y0KMm7LErz4rE6CkHIZV1JTUDlgs7XFN+GpwGKXDQtw/HsjtJuE+CS8IfEOnPg==", - "license": "MIT", - "peerDependencies": { - "jquery": ">=3 <4" - } - }, - "node_modules/jqueryui": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/jqueryui/-/jqueryui-1.11.1.tgz", - "integrity": "sha512-w3k80seYwcirTMG7fhd1MfqYx2dMO9fEi+I0vUN5hbX5+y7YIWySJkFsCBj4UBNuFcYOfUk6I63sUG/hCawdZA==", - "license": "MIT" - }, "node_modules/jsesc": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz", @@ -2989,8 +2972,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/layerr/-/layerr-3.0.0.tgz", "integrity": "sha512-tv754Ki2dXpPVApOrjTyRo4/QegVb9eVFq4mjqp4+NM5NaX7syQvN5BBNfV/ZpAHCEHV24XdUVrBAoka4jt3pA==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/linkifyjs": { "version": "4.3.3", @@ -3126,7 +3108,6 @@ "resolved": "https://registry.npmjs.org/md5/-/md5-2.3.0.tgz", "integrity": "sha512-T1GITYmFaKuO91vxyoQMFETst+O71VUPEU3ze5GNzDm0OWdP8v1ziTaAEPUr/3kLsY3Sftgz242A1SetQiDL7g==", "license": "BSD-3-Clause", - "optional": true, "dependencies": { "charenc": "0.0.2", "crypt": "0.0.2", @@ -3805,7 +3786,6 @@ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz", "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==", "license": "ISC", - "optional": true, "dependencies": { "brace-expansion": "^2.0.2" }, @@ -3963,15 +3943,6 @@ "pathe": "^2.0.1" } }, - "node_modules/moment": { - "version": "2.30.1", - "resolved": "https://registry.npmjs.org/moment/-/moment-2.30.1.tgz", - "integrity": "sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how==", - "license": "MIT", - "engines": { - "node": "*" - } - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -4013,8 +3984,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/nested-property/-/nested-property-4.0.0.tgz", "integrity": "sha512-yFehXNWRs4cM0+dz7QxCd06hTbWbSkV0ISsqBfkntU6TOY4Qm3Q88fRRLOddkGh2Qq6dZvnKVAahfhjcUvLnyA==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/node-domexception": { "version": "1.0.0", @@ -4032,7 +4002,6 @@ } ], "license": "MIT", - "optional": true, "engines": { "node": ">=10.5.0" } @@ -4042,7 +4011,6 @@ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", "license": "MIT", - "optional": true, "dependencies": { "data-uri-to-buffer": "^4.0.0", "fetch-blob": "^3.1.4", @@ -4179,7 +4147,6 @@ } ], "license": "MIT", - "optional": true, "engines": { "node": ">=14.0.0" } @@ -4205,8 +4172,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/path-posix/-/path-posix-1.0.0.tgz", "integrity": "sha512-1gJ0WpNIiYcQydgg3Ed8KzvIqTsDpNwq+cjBCssvBtuTWjEqY1AW+i+OepiEMqDCzyro9B2sLAe4RBPajMYFiA==", - "license": "ISC", - "optional": true + "license": "ISC" }, "node_modules/pathe": { "version": "2.0.3", @@ -4423,8 +4389,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.2.0.tgz", "integrity": "sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/readdirp": { "version": "5.0.0", @@ -4575,8 +4540,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/resolve": { "version": "1.22.12", @@ -4657,12 +4621,6 @@ "integrity": "sha512-6FtHJEvt+pVMIB9IBY+IcCJ6Z5f1iQnytgyfKMhDKgmzYG+TeH/wx1y3l27rshSbLiSanrR9ffZDrEsmjlQF2g==", "license": "MIT" }, - "node_modules/select2": { - "version": "4.0.13", - "resolved": "https://registry.npmjs.org/select2/-/select2-4.0.13.tgz", - "integrity": "sha512-1JeB87s6oN/TDxQQYCvS5EFoQyvV6eYMZZ0AeA4tdFDYWN3BAGZ8npr17UBFddU0lgAt3H0yjX3X6/ekOj1yjw==", - "license": "MIT" - }, "node_modules/semver": { "version": "7.8.5", "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", @@ -4794,7 +4752,6 @@ } ], "license": "MIT", - "optional": true, "dependencies": { "anynum": "^1.0.1" } @@ -4886,12 +4843,6 @@ "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==", "license": "MIT" }, - "node_modules/tabulator-tables": { - "version": "4.9.3", - "resolved": "https://registry.npmjs.org/tabulator-tables/-/tabulator-tables-4.9.3.tgz", - "integrity": "sha512-iwwQqAEGGxlgrBpcmJJvMJrfjGLcCXOB3AOb/DGkXqBy1YKoYA36hIl7qXGp6Jo8dSkzFAlDT6pKLZgyhs9OnQ==", - "license": "MIT" - }, "node_modules/tapable": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.3.3.tgz", @@ -4941,6 +4892,12 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/toastify-js": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/toastify-js/-/toastify-js-1.12.0.tgz", + "integrity": "sha512-HeMHCO9yLPvP9k0apGSdPUWrUbLnxUKNFzgUoZp1PHCLploIX/4DSQ7V8H25ef+h4iO9n0he7ImfcndnN6nDrQ==", + "license": "MIT" + }, "node_modules/tributejs": { "version": "5.1.3", "resolved": "https://registry.npmjs.org/tributejs/-/tributejs-5.1.3.tgz", @@ -4980,8 +4937,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/typescript-event-target/-/typescript-event-target-1.1.2.tgz", "integrity": "sha512-TvkrTUpv7gCPlcnSoEwUVUBwsdheKm+HF5u2tPAKubkIGMfovdSizCTaZRY/NhR8+Ijy8iZZUapbVQAsNrkFrw==", - "license": "MIT", - "optional": true + "license": "MIT" }, "node_modules/ufo": { "version": "1.6.4", @@ -5226,7 +5182,6 @@ "resolved": "https://registry.npmjs.org/url-join/-/url-join-5.0.0.tgz", "integrity": "sha512-n2huDr9h9yzd6exQVnH/jU5mr+Pfx08LRXXZhkLLetAMESRj+anQsTAh940iMrIetKAmry9coFuZQ2jY8/p3WA==", "license": "MIT", - "optional": true, "engines": { "node": "^12.20.0 || ^14.13.1 || >=16.0.0" } @@ -5236,7 +5191,6 @@ "resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.5.10.tgz", "integrity": "sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==", "license": "MIT", - "optional": true, "dependencies": { "querystringify": "^2.1.1", "requires-port": "^1.0.0" @@ -5298,6 +5252,16 @@ } } }, + "node_modules/vue-chartjs": { + "version": "5.3.4", + "resolved": "https://registry.npmjs.org/vue-chartjs/-/vue-chartjs-5.3.4.tgz", + "integrity": "sha512-x3Fqob8RQvrTdssfi9ecsCzEkFOd8JPmNwSkSQzdfKj/uBsRJs/Y88cZcZIEcPsTVfMGwMo4MOoihoDG2DoE/g==", + "license": "MIT", + "peerDependencies": { + "chart.js": "^4.1.1", + "vue": "^3.0.0-0 || ^2.7.0" + } + }, "node_modules/vue-loader": { "version": "17.4.2", "resolved": "https://registry.npmjs.org/vue-loader/-/vue-loader-17.4.2.tgz", @@ -5363,7 +5327,6 @@ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz", "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==", "license": "MIT", - "optional": true, "engines": { "node": ">= 8" } @@ -5373,7 +5336,6 @@ "resolved": "https://registry.npmjs.org/webdav/-/webdav-5.10.0.tgz", "integrity": "sha512-fVPuRLtcduVGvSO7Tn/6TQCzIvI/g6BO/+xPRctCvi/GytYpjn4czxWbh4HsArsdom9qz9BI63k9/v2HBUui1A==", "license": "MIT", - "optional": true, "dependencies": { "@buttercup/fetch": "^0.2.1", "base-64": "^1.0.0", @@ -5399,7 +5361,6 @@ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", "license": "BSD-2-Clause", - "optional": true, "engines": { "node": ">=0.12" }, @@ -5643,7 +5604,6 @@ } ], "license": "MIT", - "optional": true, "engines": { "node": ">=16.0.0" } diff --git a/js/package.json b/js/package.json index 8c45184..5c3d93b 100644 --- a/js/package.json +++ b/js/package.json @@ -21,17 +21,13 @@ }, "dependencies": { "@nextcloud/auth": "^2.6.0", + "@nextcloud/axios": "^2.6.0", + "@nextcloud/dialogs": "^7.4.0", "@nextcloud/router": "^3.1.0", "@nextcloud/vue": "^9.8.2", - "chart.js": "^2.9.4", - "daterangepicker": "^3.1.0", - "jquery": "^3.5.1", - "jquery-migrate": "^3.3.2", - "jqueryui": "^1.11.1", - "moment": "^2.29.4", - "select2": "^4.0.13", - "tabulator-tables": "^4.9.3", + "chart.js": "^4.4.9", "vue": "^3.5.39", + "vue-chartjs": "^5.3.2", "vue-router": "^4.6.4" } } diff --git a/js/src/app/api.js b/js/src/app/api.js new file mode 100644 index 0000000..9c94f08 --- /dev/null +++ b/js/src/app/api.js @@ -0,0 +1,19 @@ +import axios from '@nextcloud/axios' +import { generateUrl } from '@nextcloud/router' + +function ajaxUrl(path) { + return generateUrl('/apps/timetracker/ajax' + path) +} + +export async function apiGet(path, params = {}) { + const { data } = await axios.get(ajaxUrl(path), { params }) + return data +} + +export async function apiPost(path, body = {}) { + const { data } = await axios.post(ajaxUrl(path), body) + if (data && (data.Error || data.error)) { + throw new Error(data.Error || data.error) + } + return data +} diff --git a/js/src/app/router.js b/js/src/app/router.js index a99f795..919b616 100644 --- a/js/src/app/router.js +++ b/js/src/app/router.js @@ -1,30 +1,35 @@ import { createRouter, createWebHistory } from 'vue-router' import { generateUrl } from '@nextcloud/router' -import PlaceholderView from './views/PlaceholderView.vue' +import TagsView from './views/TagsView.vue' +import ClientsView from './views/ClientsView.vue' +import GoalsView from './views/GoalsView.vue' +import ProjectsView from './views/ProjectsView.vue' +import TimerView from './views/TimerView.vue' +import DashboardView from './views/DashboardView.vue' +import ReportsView from './views/ReportsView.vue' +import TimelinesView from './views/TimelinesView.vue' +import TimelinesAdminView from './views/TimelinesAdminView.vue' const views = [ - { path: 'timer', name: 'timer', title: 'Timer' }, - { path: 'dashboard', name: 'dashboard', title: 'Dashboard' }, - { path: 'goals', name: 'goals', title: 'Goals' }, - { path: 'reports', name: 'reports', title: 'Reports' }, - { path: 'timelines', name: 'timelines', title: 'Timelines' }, - { path: 'timelines-admin', name: 'timelines-admin', title: 'Timelines Admin' }, - { path: 'projects', name: 'projects', title: 'Projects' }, - { path: 'clients', name: 'clients', title: 'Clients' }, - { path: 'tags', name: 'tags', title: 'Tags' }, + { path: '', name: 'timer', title: 'Timer', component: TimerView }, + { path: 'dashboard', name: 'dashboard', title: 'Dashboard', component: DashboardView }, + { path: 'goals', name: 'goals', title: 'Goals', component: GoalsView }, + { path: 'reports', name: 'reports', title: 'Reports', component: ReportsView }, + { path: 'timelines', name: 'timelines', title: 'Timelines', component: TimelinesView }, + { path: 'timelines-admin', name: 'timelines-admin', title: 'Timelines Admin', component: TimelinesAdminView }, + { path: 'projects', name: 'projects', title: 'Projects', component: ProjectsView }, + { path: 'clients', name: 'clients', title: 'Clients', component: ClientsView }, + { path: 'tags', name: 'tags', title: 'Tags', component: TagsView }, ] -const routes = views.map(({ path, name, title }) => ({ +const routes = views.map(({ path, name, component }) => ({ path: `/${path}`, name, - component: PlaceholderView, - props: { title }, + component, })) -routes.push({ path: '/', redirect: '/timer' }) - export default createRouter({ - history: createWebHistory(generateUrl('/apps/timetracker/spa')), + history: createWebHistory(generateUrl('/apps/timetracker')), routes, }) diff --git a/js/src/app/views/ClientsView.vue b/js/src/app/views/ClientsView.vue new file mode 100644 index 0000000..8087ead --- /dev/null +++ b/js/src/app/views/ClientsView.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/js/src/app/views/DashboardView.vue b/js/src/app/views/DashboardView.vue new file mode 100644 index 0000000..f2ecf65 --- /dev/null +++ b/js/src/app/views/DashboardView.vue @@ -0,0 +1,169 @@ + + + + + diff --git a/js/src/app/views/GoalsView.vue b/js/src/app/views/GoalsView.vue new file mode 100644 index 0000000..86af76e --- /dev/null +++ b/js/src/app/views/GoalsView.vue @@ -0,0 +1,164 @@ + + + + + diff --git a/js/src/app/views/PlaceholderView.vue b/js/src/app/views/PlaceholderView.vue deleted file mode 100644 index ba4b11e..0000000 --- a/js/src/app/views/PlaceholderView.vue +++ /dev/null @@ -1,37 +0,0 @@ - - - diff --git a/js/src/app/views/ProjectsView.vue b/js/src/app/views/ProjectsView.vue new file mode 100644 index 0000000..1be597f --- /dev/null +++ b/js/src/app/views/ProjectsView.vue @@ -0,0 +1,282 @@ + + + + + diff --git a/js/src/app/views/ReportsView.vue b/js/src/app/views/ReportsView.vue new file mode 100644 index 0000000..67681d1 --- /dev/null +++ b/js/src/app/views/ReportsView.vue @@ -0,0 +1,214 @@ + + + + + diff --git a/js/src/app/views/TagsView.vue b/js/src/app/views/TagsView.vue new file mode 100644 index 0000000..10c9d14 --- /dev/null +++ b/js/src/app/views/TagsView.vue @@ -0,0 +1,165 @@ + + + + + diff --git a/js/src/app/views/TimelinesAdminView.vue b/js/src/app/views/TimelinesAdminView.vue new file mode 100644 index 0000000..5912a5f --- /dev/null +++ b/js/src/app/views/TimelinesAdminView.vue @@ -0,0 +1,136 @@ + + + + + diff --git a/js/src/app/views/TimelinesView.vue b/js/src/app/views/TimelinesView.vue new file mode 100644 index 0000000..9bab9f5 --- /dev/null +++ b/js/src/app/views/TimelinesView.vue @@ -0,0 +1,286 @@ + + + + + diff --git a/js/src/app/views/TimerView.vue b/js/src/app/views/TimerView.vue new file mode 100644 index 0000000..fdd0a0e --- /dev/null +++ b/js/src/app/views/TimerView.vue @@ -0,0 +1,391 @@ + + + + + diff --git a/js/src/clients.js b/js/src/clients.js deleted file mode 100644 index ae681f5..0000000 --- a/js/src/clients.js +++ /dev/null @@ -1,168 +0,0 @@ - -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -import Tabulator from 'tabulator-tables'; -require('tabulator-tables/dist/css/tabulator.css'); -require('../../css/style.css'); -//require('tabulator-tables/dist/js/jquery_wrapper.js'); -// import 'select2/dist/js/select2.full.js' -// require('select2/dist/css/select2.css'); -// require('daterangepicker/daterangepicker.css'); - -(function() { - - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - - $( function() { - - $(document).ready(function() { - $("#dialog-confirm").dialog({ - autoOpen: false, - modal: true - }); - }); - $("#new-client-submit").click(function () { - if ($("#new-client-input").val().trim() == '') - return false; - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/add-client/'+$("#new-client-input").val()); - var jqxhr = $.post( baseUrl, function() { - getClients(); - $(dialogClientEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }); - var dialogClientEditForm = $( "#dialog-client-edit-form" ).dialog({ - autoOpen: false, - height: 'auto', - width: 'auto', - modal: true, - buttons: { - "Edit client": {click:function(){ - editClient(dialogClientEditForm); - return false; - }, - text: 'Edit client', - class: 'primary' - }, - Cancel: function() { - dialogClientEditForm.dialog( "close" ); - return false; - } - }, - close: function() { - form[ 0 ].reset(); - } - }); - - var form = dialogClientEditForm.find( "form" ).on( "submit", function( event ) { - event.preventDefault(); - editClient(dialogClientEditForm); - }); - - getClients(); - function editClient(dialogClientEditForm){ - var target = dialogClientEditForm.target; - var form = dialogClientEditForm.find( "form" ); - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/edit-client/'+target); - var jqxhr = $.post( baseUrl, {name:form.find("#name").val()},function() { - getClients(); - $(dialogClientEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - .always(function() { - - }); - - } - - function getClients(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/clients'); - - var editIcon = function(cell, formatterParams){ //plain text value - return ""; - }; - - - var columns = [ - {title:"#", field:"", formatter:"rownum", width: 40, align: "center"}, - {title:"Name", field:"name", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {formatter:"buttonCross", width:40, align:"center", cellClick:function(e, cell){ - $("#dialog-confirm").dialog({ - buttons : { - "Confirm" : {click: function() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/delete-client/'+cell.getRow().getData().id); - var jqxhr = $.post( baseUrl, function() { - getClients(); - $("#dialog-confirm").dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }, - text: 'Confirm', - class:'primary' - }, - "Cancel" : function() { - $(this).dialog("close"); - } - } - }); - $("#dialog-confirm").dialog('open'); - - //cell.getRow().delete(); - }}, - {formatter:editIcon, width:40, align:"center", cellClick:function(e, cell){ - - dialogClientEditForm.target = cell.getRow().getData().id; - - form = dialogClientEditForm.find( "form" ) - form.find("#name").val(cell.getRow().getData().name); - dialogClientEditForm.dialog("open"); - - }}, - ]; - - var table = new Tabulator("#clients", { - ajaxURL:baseUrl, - layout:"fitColumns", - columns:columns, - rowClick:function(e, row){ - return false; - }, - ajaxResponse:function(url, params, response){ - - return response.Clients; //return the tableData property of a response json object - }, - }); - } - } ); -}()); diff --git a/js/src/dashboard.js b/js/src/dashboard.js deleted file mode 100644 index aa0a93e..0000000 --- a/js/src/dashboard.js +++ /dev/null @@ -1,319 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -require("daterangepicker"); -var moment = require("moment"); - -require('daterangepicker/daterangepicker.css'); -require('../../css/style.css'); - -var Chart = require("chart.js"); -Chart.plugins.register({ - afterDraw: function (chart) { - if (chart.data.datasets.length === 0 || chart.data.datasets[0].data.length === 0) { - // No data is present - var ctx = chart.chart.ctx; - var width = chart.chart.width; - var height = chart.chart.height - chart.clear(); - - ctx.save(); - ctx.textAlign = 'center'; - ctx.textBaseline = 'middle'; - ctx.font = "16px normal 'Helvetica Nueue'"; - ctx.fillText('No data to display', width / 2, height / 2); - ctx.restore(); - } - } -}); - -var dtf = require("./dateformat.js"); - -(function () { - $.ajaxSetup({ - headers: {'RequestToken': OC.requestToken} - }); - - $(function () { - $(document).ready(function () { - - var start = moment().subtract(29, 'days'); - var end = moment(); - var group1 = 'client'; - var group2 = 'project'; - var group3 = ''; - var filterProjectId = ''; - var filterClientId = ''; - var myDoughnutChart = null; - var costChart = null; - - function cb(start, end) { - $('#report-range span').html(start.format(dtf.dformat()) + ' - ' + end.format(dtf.dformat())); - } - - $("#report-range").daterangepicker({ - timePicker: false, - startDate: start, - endDate: end, - showCustomRangeLabel: false, - ranges: { - 'Today': [moment().startOf('day'), moment().endOf('day')], - 'This week': [moment().startOf('week'), moment().endOf('week')], - 'Last 7 Days': [moment().startOf('day').subtract(6, 'days'), moment().endOf('day')], - 'Last 30 Days': [moment().startOf('day').subtract(29, 'days'), moment().endOf('day')], - 'Last 90 Days': [moment().startOf('day').subtract(89, 'days'), moment().endOf('day')], - 'Last 365 Days': [moment().startOf('day').subtract(364, 'days'), moment().endOf('day')], - 'This Month': [moment().startOf('month'), moment().endOf('day')], - 'This Year': [moment().startOf('year'), moment().endOf('day')], - 'Starting last year': [moment().startOf('year').subtract(1, 'year'), moment().endOf('day')], - 'Last 3 years': [moment().startOf('day').subtract(3, 'year'), moment().endOf('day')], - 'Last 5 years': [moment().startOf('day').subtract(5, 'year'), moment().endOf('day')], - }, - locale: { - format: dtf.dformat(), - firstDay: firstDay - } - }, cb); - $("#report-range").on('apply.daterangepicker', function (ev, picker) { - //days = Math.round((picker.endDate.unix()-picker.startDate.unix()) / 86400); - start = picker.startDate; - getData(); - }); - cb(start, end); - - - var chartData = {}; - var costChartData = {}; - - getData(); - - function getData() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/report?name=&from=' + start.unix() + '&to=' + end.unix() + '&group1=' + group1 + '&group2=' + group2 + '&timegroup=' + group3 + '&filterProjectId=' + filterProjectId + '&filterClientId=' + filterClientId); - var default_colors = [ - '#3366CC', - '#DC3912', - '#FF9900', - '#109618', - '#990099', - '#3B3EAC', - '#0099C6', - '#DD4477', - '#66AA00', - '#B82E2E', - '#316395', - '#994499', - '#22AA99', - '#AAAA11', - '#6633CC', - '#E67300', - '#8B0707', - '#329262', - '#5574A6', - '#3B3EAC', - '#C71585', - '#006400', - '#4B0082', - '#8B0000', - '#FF4500', - '#BDB76B', - '#008080', - '#FFE4E1', - '#800000', - '#000080', - '#2F4F4F', - '#FF1493', - '#008000', - '#800080', - '#FF0000', - '#FF8C00', - '#20B2AA', - '#FAF0E6', - '#FFD700', - '#A52A2A', - '#708090', - '#DB7093', - '#808000', - '#9400D3', - '#FFDAB9', - '#7FFFD4' - ] - $.ajax({ - /*headers: {requesttoken: oc_requesttoken},*/ - url: baseUrl, - method: 'GET', - dataType: 'json', - success: function (d) { - chartData = { - labels: [], - datasets: [{data: [], backgroundColor: []}, {data: [], backgroundColor: []},], - }; - costChartData = { - labels: [], - datasets: [{data: [], backgroundColor: []}, {data: [], backgroundColor: []},], - }; - var clientMap = {}; - var nclients = 0; - var totalCost = 0; - // extract clients in clientMap - var totalMinutes = 0; - for (var x = 0; x < d.items.length; x++) { - cid = d.items[x].client; - if (cid == null) { - cid = -1; - } - if (clientMap[cid] === undefined) { - clientMap[cid] = { - duration: d.items[x].totalDuration, - order: nclients, - client: (d.items[x].client == null) ? 'Not Set' : d.items[x].client, - cost: d.items[x].cost - } - totalMinutes += d.items[x].totalDuration / 60.0; - totalCost += d.items[x].cost; - nclients++; - } else { - clientMap[cid].duration = clientMap[cid].duration + d.items[x].totalDuration; - clientMap[cid].cost = clientMap[cid].cost + d.items[x].cost; - totalMinutes += d.items[x].totalDuration / 60.0; - totalCost += d.items[x].cost; - } - } - var mx = 0; - var nindex = nclients; - - var sortable = []; - for (var client in clientMap) { - sortable.push([client, clientMap[client].order]); - } - - sortable.sort(function (a, b) { - return a[1] - b[1]; - }); - for (var i = 0; i < sortable.length; i++) { - t = sortable[i]; - key = t[0]; - - // first add clients - chartData.datasets[0].data[clientMap[key].order] = clientMap[key].duration / 60.0; - chartData.datasets[1].data[clientMap[key].order] = 0; - - costChartData.datasets[0].data[clientMap[key].order] = (clientMap[key].cost / 100); - costChartData.datasets[1].data[clientMap[key].order] = 0; - - if (clientMap[key].client == -1) { - chartData.labels[clientMap[key].order] = "Client Not Set"; - costChartData.labels[clientMap[key].order] = "Client Not Set"; - - } else { - chartData.labels[clientMap[key].order] = clientMap[key].client; - costChartData.labels[clientMap[key].order] = clientMap[key].client; - } - chartData.datasets[0].backgroundColor[clientMap[key].order] = default_colors[clientMap[key].order]; - chartData.datasets[1].backgroundColor[clientMap[key].order] = default_colors[clientMap[key].order]; - - costChartData.datasets[0].backgroundColor[clientMap[key].order] = default_colors[clientMap[key].order]; - costChartData.datasets[1].backgroundColor[clientMap[key].order] = default_colors[clientMap[key].order]; - // add projects for each client - - for (var x = 0; x < d.items.length; x++) { - - if (d.items[x].client === key || (d.items[x].client == null && key == -1)) { - chartData.datasets[0].data[nindex] = 0; - chartData.datasets[1].data[nindex] = d.items[x].totalDuration / 60.0; - - costChartData.datasets[0].data[nindex] = 0; - costChartData.datasets[1].data[nindex] = d.items[x].cost; - - chartData.datasets[1].backgroundColor[nindex] = default_colors[nindex]; - chartData.datasets[0].backgroundColor[nindex] = default_colors[nindex]; - - costChartData.datasets[1].backgroundColor[nindex] = default_colors[nindex]; - costChartData.datasets[0].backgroundColor[nindex] = default_colors[nindex]; - - - if (d.items[x].project == null) { - chartData.labels[nindex] = "Project Not Set"; - costChartData.labels[nindex] = "Project Not Set" - } else { - chartData.labels[nindex] = d.items[x].project; - costChartData.labels[nindex] = d.items[x].project; - } - nindex++; - } - } - } - ; - - console.log(chartData); - console.log(costChartData); - if (myDoughnutChart != null) { - myDoughnutChart.destroy(); - } - - if (costChart != null) { - costChart.destroy(); - } - - var ctx = document.getElementById("myChart").getContext("2d"); - - myDoughnutChart = new Chart(ctx, { - type: 'doughnut', - data: chartData, - options: { - tooltips: { - callbacks: { - title: function (tooltipItem, data) { - return data['labels'][tooltipItem[0]['index']]; - }, - label: function (tooltipItem, data) { - - mm = data['datasets'][tooltipItem.datasetIndex]['data'][tooltipItem['index']]; - h = Math.trunc(mm / 60); - m = Math.trunc(mm % 60); - return (h + " hours " + m + " minutes") - }, - afterLabel: function (tooltipItem, data) { - var dataset = data['datasets'][tooltipItem.datasetIndex]; - if (!(0 in dataset["_meta"])) - return ''; - var percent = Math.round((dataset['data'][tooltipItem['index']] / dataset["_meta"][0]['total']) * 100) - return '(' + percent + '%)'; - }, - }, - - } - } - }); - - var costChartCtx = document.getElementById("costChart").getContext("2d"); - - costChart = new Chart(costChartCtx, { - type: 'doughnut', - data: costChartData, - options: { - tooltips: { - callbacks: { - title: function (tooltipItem, data) { - return data['labels'][tooltipItem[0]['index']]; - }, - label: function (tooltipItem, data) { - var c = data['datasets'][tooltipItem.datasetIndex]['data'][tooltipItem['index']]; - return "Cost: " + (c / 100).toFixed(2); - } - }, - - } - } - }); - - h = Math.trunc(totalMinutes / 60); - m = Math.trunc(totalMinutes % 60); - $('#summary').html('Total time: ' + h + " hours " + m + " minutes" + "
    " + "Total costs: " + (totalCost / 100).toFixed(2)); - } - }); - } - }); - }); -}()); diff --git a/js/src/dateformat.js b/js/src/dateformat.js deleted file mode 100644 index 1925632..0000000 --- a/js/src/dateformat.js +++ /dev/null @@ -1,53 +0,0 @@ -var moment = require("moment"); -moment.locale(document.documentElement.getAttribute("data-locale") || undefined); -const dformat = moment.localeData().longDateFormat('L'); -const tformat = moment.localeData().longDateFormat('LTS'); - -exports.dformat = function () { - return dformat; -}; - -exports.tformat = function () { - return tformat; -}; - -exports.dtformat = function () { - return dformat + ' ' + tformat; -}; - -exports.mformat = function () { - var sample; - - try { - sample = window.Intl ? new Intl.DateTimeFormat((document.documentElement.getAttribute("data-locale") || undefined), { - numberingSystem: 'latn', - calendar: 'gregory', - }).format(new Date(1970, 11, 31)) : ''; - } catch { - sample = window.Intl ? new Intl.DateTimeFormat(undefined, { - numberingSystem: 'latn', - calendar: 'gregory', - }).format(new Date(1970, 11, 31)) : ''; - } - - let mm = 0, - mi = sample.indexOf(12); - let dd = 1, - di = sample.indexOf(31); - let yy = 2, - yi = sample.indexOf(1970); - - // IE 10 or earlier, iOS 9 or earlier, non-Latin numbering system - // or non-Gregorian calendar; fall back to mm/dd/yyyy - if (yi >= 0 && mi >= 0 && di >= 0) { - mm = (mi > yi) + (mi > di); - dd = (di > yi) + (di > mi); - yy = (yi > mi) + (yi > di); - } - - let r = []; - r[yy] = 'YYYY'; - r[mm] = 'MM'; - - return r.join(sample.match(/[-.]/) || '/').replace('//','/'); -}; diff --git a/js/src/goals.js b/js/src/goals.js deleted file mode 100644 index cc9d196..0000000 --- a/js/src/goals.js +++ /dev/null @@ -1,163 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -import Tabulator from 'tabulator-tables'; -require('tabulator-tables/dist/css/tabulator.css'); - -import 'select2/dist/js/select2.full.js' -require('select2/dist/css/select2.css'); - -require('../../css/style.css'); -(function() { - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - - $( function() { - var newGoalProjectId; - $(document).ready(function() { - $("#dialog-confirm").dialog({ - autoOpen: false, - modal: true - }); - }); - - - $("#project-select").select2({ - width: '200px', - escapeMarkup : function(markup) { return markup; }, - placeholder: "Select project", - allowClear: true, - templateResult: function formatState (project) { - var color = '#ffffff'; - if (project.color) { - color = project.color; - } - var $state = $( - '' + project.text + '' - ); - return $state; - }, - ajax: { - tags: true, - url: OC.generateUrl('/apps/timetracker/ajax/projects'), - - dataType: 'json', - delay: 250, - - processResults: function (data, page) { //json parse - return { - results: $.map(data.Projects,function(val, i){ - return { id: val.id, text:val.name, color: val.color}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - - }, - }); - $('#project-select').on("select2:select select2:unselect", function(e) { - newGoalProjectId = ($(e.target).val() != null)? $(e.target).val() : ""; - }); - - - $("#new-goal-submit").click(function () { - if ($("#new-goal-hours").val().trim() == '') - return false; - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/add-goal'); - var jqxhr = $.post( baseUrl, { - projectId : newGoalProjectId, - hours: $("#new-goal-hours").val(), - interval: $("#new-goal-interval").val(), - }, function() { - - getGoals(); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }); - - getGoals(); - function getGoals(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/goals'); - - var editIcon = function(cell, formatterParams){ //plain text value - return ""; - }; - - - var columns = [ - {title:"#", field:"", formatter:"rownum", width: 40, align: "center"}, - {title:"Project", field:"projectName", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Target Hours", field:"hours", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Interval", field:"interval", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Started At", field:"createdAt", widthGrow:1, mutator: function(value, data, type, params, component){ - return new Date(data.createdAt*1000).toDateString();} - }, //column will be allocated 1/5 of the remaining space - {title:"Hours spent current interval", field:"workedHoursCurrentPeriod", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Past Debt in Hours", field:"debtHours", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Remaining Hours", field:"remainingHours", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Total Remaining Hours", field:"totalRemainingHours", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {formatter:"buttonCross", width:40, align:"center", cellClick:function(e, cell) { - $("#dialog-confirm").dialog({ - buttons : { - "Confirm" : {click: function() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/delete-goal/'+cell.getRow().getData().id); - var jqxhr = $.post( baseUrl, function() { - getGoals(); - $("#dialog-confirm").dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }, - text: 'Confirm', - class:'primary' - }, - "Cancel" : function() { - $(this).dialog("close"); - } - } - }); - $("#dialog-confirm").dialog('open'); - - //cell.getRow().delete(); - }}, - - ]; - - var table = new Tabulator("#goals", { - ajaxURL:baseUrl, - layout:"fitColumns", - columns:columns, - rowClick:function(e, row){ - return false; - }, - ajaxResponse:function(url, params, response){ - - return response.Goals; //return the tableData property of a response json object - }, - }); - } - } ); -}()); diff --git a/js/src/piklor.js b/js/src/piklor.js deleted file mode 100644 index 3598c73..0000000 --- a/js/src/piklor.js +++ /dev/null @@ -1,161 +0,0 @@ -(function (root) { - - /** - * Piklor - * Creates a new `Piklor` instance. - * - * @name Piklor - * @function - * @param {String|Element} sel The element where the color picker will live. - * @param {Array} colors An array of strings representing colors. - * @param {Object} options An object containing the following fields: - * - * - `open` (String|Element): The HTML element or query selector which will open the picker. - * - `openEvent` (String): The open event (default: `"click"`). - * - `style` (Object): Some style options: - * - `display` (String): The display value when the picker is opened (default: `"block"`). - * - `template` (String): The color item template. The `{color}` snippet will be replaced - * with the color value (default: `"

    "`). - * - `autoclose` (Boolean): If `false`, the color picker will not be hided by default (default: `true`). - * - `closeOnBlur` (Boolean): If `true`, the color picker will be closed when clicked outside of it (default: `false`). - * - * @return {Piklor} The `Piklor` instance. - */ - function Piklor(sel, colors, options) { - var self = this; - options = options || {}; - options.open = self.getElm(options.open); - options.openEvent = options.openEvent || "click"; - options.style = Object(options.style); - options.style.display = options.style.display || "inline-block"; - options.closeOnBlur = options.closeOnBlur || false; - options.template = options.template || "
    "; - self.elm = self.getElm(sel); - self.cbs = []; - self.isOpen = true; - self.colors = colors; - self.options = options; - self.render(); - - // Handle the open element and event. - if (options.open) { - options.open.addEventListener(options.openEvent, function (ev) { - self.isOpen ? self.close() : self.open(); - ev.preventDefault(); - return false; - }); - } - - // Click on colors - self.elm.addEventListener("click", function (ev) { - var col = ev.target.getAttribute("data-col"); - if (!col) { return; } - self.close(); - self.set(col); - }); - - if (options.closeOnBlur) { - window.addEventListener("click", function (ev) { - // check if we didn't click 'open' and 'color pallete' elements - if (ev.target != options.open && ev.target != self.elm && self.isOpen) { - self.close(); - } - }); - } - - if (options.autoclose !== false) { - self.close(); - } - } - - /** - * getElm - * Finds the HTML element. - * - * @name getElm - * @function - * @param {String|Element} el The HTML element or query selector. - * @return {HTMLElement} The selected HTML element. - */ - Piklor.prototype.getElm = function (el) { - if (typeof el === "string") { - return document.querySelector(el); - } - return el; - }; - - /** - * render - * Renders the colors. - * - * @name render - * @function - */ - Piklor.prototype.render = function () { - var self = this - , html = "" - ; - - self.colors.forEach(function (c) { - html += self.options.template.replace(/\{color\}/g, c); - }); - - self.elm.innerHTML = html; - }; - - /** - * close - * Closes the color picker. - * - * @name close - * @function - */ - Piklor.prototype.close = function () { - this.elm.style.display = "none"; - this.isOpen = false; - }; - - /** - * open - * Opens the color picker. - * - * @name open - * @function - */ - Piklor.prototype.open = function () { - this.elm.style.display = this.options.style.display; - this.isOpen = true; - }; - - /** - * colorChosen - * Adds a new callback in the colorChosen callback buffer. - * - * @name colorChosen - * @function - * @param {Function} cb The callback function called with the selected color. - */ - Piklor.prototype.colorChosen = function (cb) { - this.cbs.push(cb); - }; - - /** - * set - * Sets the color picker color. - * - * @name set - * @function - * @param {String} c The color to set. - * @param {Boolean} p If `false`, the `colorChosen` callbacks will not be called. - */ - Piklor.prototype.set = function (c, p) { - var self = this; - self.color = c; - if (p === false) { return; } - self.cbs.forEach(function (cb) { - cb.call(self, c); - }); - }; - - root.Piklor = Piklor; -})(this); diff --git a/js/src/projects.js b/js/src/projects.js deleted file mode 100644 index 63c2f92..0000000 --- a/js/src/projects.js +++ /dev/null @@ -1,487 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -import Tabulator from 'tabulator-tables'; -require('tabulator-tables/dist/css/tabulator.css'); -import 'select2/dist/js/select2.full.js' -require('select2/dist/css/select2.css'); -require('../../css/style.css'); -//require("piklor.js"); -var Piklor = require('./piklor.js'); -require('../../css/piklor.css'); - -(function() { - var colorArray = [ - "#1abc9c" - , "#2ecc71" - , "#3498db" - , "#9b59b6" - , "#34495e" - , "#16a085" - , "#27ae60" - , "#2980b9" - , "#8e44ad" - , "#2c3e50" - , "#f1c40f" - , "#e67e22" - , "#e74c3c" - , "#ecf0f1" - , "#95a5a6" - , "#f39c12" - , "#d35400" - , "#c0392b" - , "#bdc3c7" - , "#7f8c8d" - , "#bf678b" - , "#bf678b" - , "#c98879" - , "#ddcb55" - , "#a5b872" - , "#6ea68f" - , "#3794ac" - , "#0082c9" - , "#2d73be" - , "#5b64b3" - , "#8855a8" -]; - - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - $( function() { - var pkedit = null; - function isAdmin(){ - return oc_isadmin; - } - - $(document).ready(function() { - - $("#dialog-confirm").dialog({ - autoOpen: false, - modal: true - }); - var pk = new Piklor.Piklor("#color-picker-project-new", colorArray, { - open: ".picker-wrapper .btn" - }) - , wrapperEl = pk.getElm(".picker-wrapper") - , header = pk.getElm("header") - , footer = pk.getElm("footer") - ; - pk.colorChosen(function (col) { - wrapperEl.style.backgroundColor = col; - header.style.backgroundColor = col; - $('#new-project-color').val(col); - //footer.style.backgroundColor = col; - }); - - - // OC.currentUser - - $("#client-select").select2({ - width: '200px', - placeholder: 'Select client...', - allowClear: true, - ajax: { - url: OC.generateUrl('/apps/timetracker/ajax/clients'), - - dataType: 'json', - delay: 250, - processResults: function (data, page) { //json parse - return { - results: $.map(data.Clients,function(val, i){ - return { id: val.id, text:val.name}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - } - }); - - getProjects(); - }); - $('#show-archived-projects').change(function (e){ - getProjects(); - }); - $("#new-project-submit").click(function (e) { - e.preventDefault(); - var selectedClient = $('#client-select').select2('data'); - var selectedColor = $('#new-project-color').val(); - var clientId = null; - if (selectedClient.length > 0){ - clientId = selectedClient[0].id; - } - if ($("#new-project-input").val().trim() == '') - return false; - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/add-project/'+$("#new-project-input").val()); - var jqxhr = $.post( baseUrl, {clientId:clientId, color:selectedColor} ,function() { - getProjects(); - $(dialogProjectEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }); - return false; - }); - var dialogProjectEditForm = $( "#dialog-project-edit-form" ).dialog({ - autoOpen: false, - height: 'auto', - width: 'auto', - modal: true, - create: function( event, ui ) { - - var wrapperEl; - var header; - var footer; - pkedit = new Piklor.Piklor("#color-picker-project-edit", colorArray, { - open: ".picker-wrapper-project-edit .btn" - }) - , wrapperEl = pkedit.getElm(".picker-wrapper-project-edit") - , header = pkedit.getElm("header") - , footer = pkedit.getElm("footer") - ; - pkedit.colorChosen(function (col) { - wrapperEl.style.backgroundColor = col; - //header.style.backgroundColor = col; - $('#project-edit-color').val(col); - //footer.style.backgroundColor = col; - }); - - if (isAdmin()){ - $(".admin-only").removeClass('hidden'); - $('#locked').click(function(){ - if($('#locked').is(':checked')){ - $("#locked-options").removeClass('hidden'); - } else { - $("#locked-options").addClass('hidden'); - } - - }); - } else { - $(".admin-only").hide(); - } - - - - $("#locked-select-tags").select2({ - tags: true, - width: '200px', - placeholder: "Select tags...", - allowClear: true, - ajax: { - url: OC.generateUrl('/apps/timetracker/ajax/tags'), - formatNoMatches: function() { - return ''; - }, - dataType: 'json', - delay: 250, - processResults: function (data) { //json parse - return { - results: $.map(data.Tags,function(val, i){ - return { id: val.id, text:val.name}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - }, - }); - - - - - $("#locked-select-users").select2({ - tags: true, - width: '200px', - placeholder: "Select users...", - allowClear: true, - results: function(data) { - lastResults = data.results; - return {results: data}; - }, - ajax: { - headers: { - "requesttoken" : oc_requesttoken, - - }, - url: OC.generateUrl('/ocs/v2.php/cloud/users/details'), - formatNoMatches: function() { - return ''; - }, - dataType: 'json', - delay: 250, - processResults: function (data, page) { //json parse - return { - results: $.map(data.ocs.data.users,function(val, i){ - return { id: i, text:val.displayname}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - }, - } - ); - - - - - $("#client-select-popup").select2({ - width: '200px', - placeholder: 'Select client...', - allowClear: true, - ajax: { - url: OC.generateUrl('/apps/timetracker/ajax/clients'), - - dataType: 'json', - delay: 250, - processResults: function (data, page) { //json parse - return { - results: $.map(data.Clients,function(val, i){ - return { id: val.id, text:val.name}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - }, - }); - $('input.select2-input').attr('autocomplete', "xxxxxxxxxxx") - }, - buttons: { - "Delete project": { text:'Delete project', - click:function(){ - - $("#dialog-confirm").dialog({ - buttons : { - "Confirm" : {click: function() { - deleteProject(dialogProjectEditForm); - $("#dialog-confirm").dialog("close"); - }, - - text: 'Confirm', - class:'primary' - }, - "Cancel" : function() { - $(this).dialog("close"); - } - } - }); - $("#dialog-confirm").dialog('open'); - - - }, class:'redButton admin-only'}, - "Edit project": { text:'Edit project', - click:function(){ - editProject(dialogProjectEditForm); - }, class:'primary'}, - Cancel: function() { - dialogProjectEditForm.dialog( "close" ); - } - }, - close: function() { - form[ 0 ].reset(); - } - }); - - var form = dialogProjectEditForm.find( "form" ).on( "submit", function( event ) { - event.preventDefault(); - editProject(dialogProjectEditForm); - }); - - - function editProject(dialogProjectEditForm){ - var target = dialogProjectEditForm.target; - var form = dialogProjectEditForm.find( "form" ); - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/edit-project/'+target.getData().id); - var jqxhr = $.post( baseUrl, { - name:form.find("#name").val(), - clientId:form.find("#client-select-popup").val(), - color:form.find("#project-edit-color").val(), - locked:form.find("#locked").is(':checked')?'1':'0', - archived:form.find("#archived").is(':checked')?'1':'0', - allowedTags:$("#locked-select-tags").val().join(","), - allowedUsers:$("#locked-select-users").val().join(",") - },function() { - getProjects(); - $(dialogProjectEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }); - - } - function deleteProject(dialogProjectEditForm){ - var target = dialogProjectEditForm.target; - var form = dialogProjectEditForm.find( "form" ); - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/delete-project-with-data/'+target.getData().id); - var jqxhr = $.post( baseUrl, {name:form.find("#name").val(), clientId:form.find("#client-select-popup").val(), locked:form.find("#locked").is(':checked')?'1':'0',archived:form.find("#archived").is(':checked')?'1':'0', allowedTags:form.find("#locked-select-tags").val(), allowedUsers:form.find("#locked-select-users").val() },function() { - getProjects(); - $(dialogProjectEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }); - - } - function getProjects(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/projects-table'); - - var columns = [ - //{title:"Id", field:"id", width:100}, //column has a fixed width of 100px; - {title:"#", field:"", formatter:"rownum", width: 40, align: "center"}, - {title:"Color", field:"color", formatter:"color", width: 40}, //column will be allocated 1/5 of the remaining space - {title:"Name", field:"name", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Client", field:"client", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Locked", field:"locked", widthGrow:1, formatter:"tickCross"}, //column will be allocated 1/5 of the remaining space - ]; - var adminColumns = [ - //{title:"Locked", field:"locked", widthGrow:1, formatter:"tickCross"}, //column will be allocated 1/5 of the remaining space - {title:"Allowed Users", field:"allowedUsers", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Allowed Tags", field:"allowedTags", widthGrow:1, mutator: function(value, data, type, params, component){ - data.origAllowedTags = data.allowedTags; - return data.allowedTags.map(function(d) { - return d.name; - }).join(', '); }}, //column will be allocated 1/5 of the remaining space - ]; - if (isAdmin()){ - columns = columns.concat(adminColumns); - } - if ($("#show-archived-projects").is(':checked')){ - columns = columns.concat([{title:"Archived", field:"archived", widthGrow:1, formatter:"tickCross"}]); - } - - var table = new Tabulator("#projects", { - ajaxURL:baseUrl+"?archived="+($("#show-archived-projects").is(':checked')?'1':'0'), - layout:"fitColumns", - columns:columns, - rowClick:function(e, row){ - - if (!isAdmin() && row.getData().locked){ - return false; - } - e.preventDefault(); - dialogProjectEditForm.target = row; - - form = dialogProjectEditForm.find( "form" ) - form.find("#name").val(row.getData().name); - form.find("#project-edit-color").val(row.getData().color); - pkedit.set(row.getData().color); - //form.find("#client-select-popup").val($(e.target).data("client-id")).trigger('change'); - var clientSelectData = { - clientId: row.getData().clientId, - clientName: row.getData().client, - }; - - if (clientSelectData.clientId != null){ - $('#client-select-popup').append( - '' - ); - $("#client-select-popup").trigger('change'); - } - - form.find("#archived").prop('checked', row.getData().archived); - if (isAdmin()){ - var tags = row.getData().origAllowedTags.map(function(e){ return e.id;}); - var users = row.getData().allowedUsers; - - $.ajax(OC.generateUrl('/apps/timetracker/ajax/tags'), { - dataType: "json" - }).done(function(data) { - $('#locked-select-tags').html(''); - $.each(data.Tags, function( index, value ){ - if (tags.includes(value.id) ){ - var option = new Option(value.name, value.id, true, true); - $('#locked-select-tags').append(option).trigger('change'); - - } - } - ); - $('#locked-select-tags').trigger({ - type: 'select2:select', - params: { - data: data - } - }); - - }); - - $.ajax(OC.generateUrl('/ocs/v2.php/cloud/users/details'), { - dataType: "json", - headers: { - "requesttoken" : oc_requesttoken, - - }, - }).done(function(data) { - - var userMap = $.map(data.ocs.data.users,function(val, i){ - return { id: i, text:val.displayname}; - }); - - $('#locked-select-users').val(null).trigger('change'); - $('#locked-select-users').html(''); - $.each(userMap, function( index, value ){ - if (users.includes(value.text) ){ - var option = new Option(value.text, value.id, true, true); - $('#locked-select-users').append(option).trigger('change'); - - } - } - ); - $('#locked-select-users').trigger({ - type: 'select2:select', - params: { - data: data - } - }); - }); - - form.find("#locked").prop('checked', row.getData().locked); - if($('#locked').is(':checked')){ - $("#locked-options").removeClass('hidden'); - } else { - $("#locked-options").addClass('hidden'); - } - } - dialogProjectEditForm.dialog("open"); - return false; - }, - ajaxResponse:function(url, params, response){ - - return response.items; //return the tableData property of a response json object - }, - }); - - } - - - } ); -}()); diff --git a/js/src/reports.js b/js/src/reports.js deleted file mode 100644 index a154de1..0000000 --- a/js/src/reports.js +++ /dev/null @@ -1,296 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -require("daterangepicker"); -import Tabulator from 'tabulator-tables'; -require('tabulator-tables/dist/css/tabulator.css'); -require('daterangepicker/daterangepicker.css'); -import 'select2/dist/js/select2.full.js' -require('select2/dist/css/select2.css'); -require('../../css/style.css'); - -var dtf = require("./dateformat.js"); - -(function() { - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - $( function() { - - var group1 = "project"; - var group2 = "user"; - var group3 = "day"; - var filterProjectId = ""; - var filterClientId = ""; - - $(document).ready(function() { - $("#dialog-confirm").dialog({ - autoOpen: false, - modal: true - }); - - var start = moment().subtract(29, 'days'); - var end = moment(); - function cb(start, end) { - $('#report-range span').html(start.format(dtf.dformat()) + ' - ' + end.format(dtf.dformat())); - } - $("#report-range").daterangepicker({ - timePicker: false, - startDate: start, - endDate: end, - ranges: { - 'Today': [moment(), moment()], - 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')], - 'Last 7 Days': [moment().subtract(6, 'days'), moment()], - 'Last 30 Days': [moment().subtract(29, 'days'), moment()], - 'Last 90 Days': [moment().subtract(89, 'days'), moment()], - 'Last 365 Days': [moment().subtract(364, 'days'), moment()], - 'This Month': [moment().startOf('month'), moment().endOf('month')], - 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')], - 'The Month Before Last': [moment().subtract(2, 'month').startOf('month'), moment().subtract(2, 'month').endOf('month')], - 'This Year': [moment().startOf('year'), moment().endOf('year')], - 'Last Year': [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')], - - }, - locale: { - format: dtf.dformat(), - firstDay: firstDay - } - },cb); - $("#report-range").on('apply.daterangepicker', function(ev, picker) { - start = picker.startDate; - end = picker.endDate; - getReport(); - }); - cb(start, end); - $("#group1").select2(); - $("#group2").select2(); - $("#group3").select2(); - $('#group1').on("select2:select select2:unselect", function(e) { - group1 = e.params.data.id; - getReport(); - }); - $('#group2').on("select2:select select2:unselect", function(e) { - group2 = e.params.data.id; - getReport(); - }); - $('#group3').on("select2:select select2:unselect", function(e) { - group3 = e.params.data.id; - getReport(); - }); - getReport(); - $("#filter-project").select2({ - width: '200px', - escapeMarkup : function(markup) { return markup; }, - placeholder: "Select project", - allowClear: true, - templateResult: function formatState (project) { - var color = '#ffffff'; - if (project.color) { - color = project.color; - } - var $state = $( - '' + project.text + '' - ); - return $state; - }, - ajax: { - tags: true, - url: OC.generateUrl('/apps/timetracker/ajax/projects'), - - dataType: 'json', - delay: 250, - - processResults: function (data, page) { //json parse - return { - results: $.map(data.Projects,function(val, i){ - return { id: val.id, text:val.name, color: val.color}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - - }, - }); - - $('#filter-project').on("select2:select select2:unselect", function(e) { - - - filterProjectId = ($(e.target).val() != null)? $(e.target).val() : ""; - getReport(); - }); - - - - $("#filter-client").select2({ - tags: true, - width: '200px', - escapeMarkup : function(markup) { return markup; }, - placeholder: "Select client", - allowClear: true, - ajax: { - tags: true, - url: OC.generateUrl('/apps/timetracker/ajax/clients'), - - dataType: 'json', - delay: 250, - processResults: function (data, page) { //json parse - return { - results: $.map(data.Clients,function(val, i){ - return { id: val.id, text:val.name}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - - }, - }); - - - $('#filter-client').on("select2:select select2:unselect", function(e) { - - - filterClientId = ($(e.target).val() != null)? $(e.target).val() : ""; - getReport(); - }); - - - $('input.select2-input').attr('autocomplete', "xxxxxxxxxxx"); - - - - function getReport(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/report?name=&from='+start.unix()+'&to='+end.unix()+'&group1='+group1+'&group2='+group2+'&timegroup='+group3+'&filterProjectId='+filterProjectId+'&filterClientId='+filterClientId); - function pad(n, width, z) { - z = z || '0'; - n = n + ''; - return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; - } - var endedAccessor = function(value, data, type, params, column){ - if (group1 != '' || group2 != '' || group3 != ''){ - return '*'; - } - return moment(data.time, dtf.dtformat()).add(moment.duration(data.totalDuration)).format(dtf.dtformat()); - } - var totalDurationAccessor = function(value, data, type, params, column){ - var s = Math.floor( (data.totalDuration) % 60 ); - var m = Math.floor( (data.totalDuration/60) % 60 ); - var h = Math.floor( (data.totalDuration/(60*60))); - return pad(h,2) + ':' + pad(m,2) + ':' + pad(s,2); - } - var whenAccessor = function(value, data, type, params, column){ - switch(group3) { - case 'day': - return moment.unix(value).format(dtf.dformat()); - case 'month': - return moment.unix(value).format(dtf.mformat()); - case 'week': - return moment.unix(value).format('YYYY[W]W'); - case 'year': - return moment.unix(value).format('YYYY'); - default: - return moment.unix(value).format(dtf.dtformat()); - } - } - var nullCheckAccessor = function(value, data, type, params, column){ - return value ? value : ''; - } - - var money = function(value, data, type, params, component) { - return value / 100; - } - var table = new Tabulator("#report", { - ajaxURL:baseUrl, - layout:"fitColumns", - columns:[ - //{title:"Id", field:"id", width:100}, //column has a fixed width of 100px; - {title:"#", field:"id", formatter:"rownum"}, - {title:"Name", field:"name", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Details", field:"details", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"User", field:"userUid", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Project", field:"project",accessorDownload:nullCheckAccessor, widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Client", field:"client",accessorDownload:nullCheckAccessor, widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"When", field:"time", widthGrow:1,accessorDownload:whenAccessor,formatter:function(cell, formatterParams, onRendered){ - var t = cell.getValue(); - switch(group3) { - case 'day': - return moment.unix(t).format(dtf.dformat()); - case 'month': - return moment.unix(t).format(dtf.mformat()); - case 'week': - return moment.unix(t).format('YYYY[W]W'); - case 'year': - return moment.unix(t).format('YYYY'); - default: - return moment.unix(t).format(dtf.dtformat()); - } - }}, - {title:"Cost", field:"cost", mutator:money, accessorDownload: nullCheckAccessor, widthGrow:1, bottomCalc: "sum", formatter: "money", bottomCalcFormatter: "money"}, //column will be allocated 1/5 of the remaining space - {title:"Total Duration", field:"totalDuration",accessorDownload:totalDurationAccessor,formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var duration = cell.getValue(); - var s = Math.floor( (duration) % 60 ); - var m = Math.floor( (duration/60) % 60 ); - var h = Math.floor( (duration/(60*60))); - return pad(h,2) + ':' + pad(m,2) + ':' + pad(s,2); - - },bottomCalc:"sum", bottomCalcParams:{ - precision:1, - },bottomCalcFormatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var duration = cell.getValue(); - var s = Math.floor( (duration) % 60 ); - var m = Math.floor( (duration/60) % 60 ); - var h = Math.floor( (duration/(60*60))); - - return pad(h,2) + ':' + pad(m,2) + ':' + pad(s,2); - - }}, //column will be allocated 1/5 of the remaining space - {title:"Ended", field:"ended",visible:false,accessorDownload:endedAccessor,formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - if (group1 != '' || group2 != '' || group3 != ''){ - return '*'; - } - var time = cell.getRow().getData().time; - var duration = cell.getRow().getData().totalDuration; - return moment.unix(parseInt(time) + parseInt(duration)).format(dtf.dtformat()); - - }}, - ], - ajaxResponse:function(url, params, response){ - - return response.items; //return the tableData property of a response json object - }, - }); - $("#download-csv").off().click(function(){ - table.showColumn("ended"); - table.download("csv", "data.csv"); - table.hideColumn("ended"); - return false; - }); - $("#download-json").off().click(function(){ - table.showColumn("ended"); - table.download("json", "data.json"); - table.hideColumn("ended"); - return false; - }); - } - }); - - - } ); -}()); diff --git a/js/src/tags.js b/js/src/tags.js deleted file mode 100644 index 8ddb09d..0000000 --- a/js/src/tags.js +++ /dev/null @@ -1,158 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -import Tabulator from 'tabulator-tables'; -require('tabulator-tables/dist/css/tabulator.css'); -require('../../css/style.css'); -(function() { - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - - $( function() { - - $(document).ready(function() { - $("#dialog-confirm").dialog({ - autoOpen: false, - modal: true - }); - }); - - $("#new-tag-submit").click(function () { - if ($("#new-tag-input").val().trim() == '') - return false; - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/add-tag/'+$("#new-tag-input").val()); - var jqxhr = $.post( baseUrl, function() { - - getTags(); - $(dialogTagEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }); - var dialogTagEditForm = $( "#dialog-tag-edit-form" ).dialog({ - autoOpen: false, - height: 'auto', - width: 'auto', - modal: true, - buttons: { - "Edit tag": {click: function(){ - editTag(dialogTagEditForm); - return false; - }, - text: 'Edit tag', - class:'primary' - }, - Cancel: function() { - dialogTagEditForm.dialog( "close" ); - } - }, - close: function() { - form[ 0 ].reset(); - } - }); - - var form = dialogTagEditForm.find( "form" ).on( "submit", function( event ) { - event.preventDefault(); - editTag(dialogTagEditForm); - }); - - getTags(); - function editTag(dialogTagEditForm){ - var target = dialogTagEditForm.target; - var form = dialogTagEditForm.find( "form" ); - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/edit-tag/'+target); - var jqxhr = $.post( baseUrl, {name:form.find("#name").val()},function() { - getTags(); - $(dialogTagEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - - } - function getTags(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/tags'); - - var editIcon = function(cell, formatterParams){ //plain text value - return ""; - }; - - - var columns = [ - {title:"#", field:"", formatter:"rownum", width: 40, align: "center"}, - {title:"Name", field:"name", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {formatter:"buttonCross", width:40, align:"center", cellClick:function(e, cell){ - $("#dialog-confirm").dialog({ - buttons : { - "Confirm" : {click: function() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/delete-tag/'+cell.getRow().getData().id); - var jqxhr = $.post( baseUrl, function() { - getTags(); - $("#dialog-confirm").dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }, - text: 'Confirm', - class:'primary' - }, - "Cancel" : function() { - $(this).dialog("close"); - } - } - }); - $("#dialog-confirm").dialog('open'); - - //cell.getRow().delete(); - }}, - {formatter:editIcon, width:40, align:"center", cellClick:function(e, cell){ - - dialogTagEditForm.target = cell.getRow().getData().id; - - form = dialogTagEditForm.find( "form" ) - form.find("#name").val(cell.getRow().getData().name); - dialogTagEditForm.dialog("open"); - - }}, - ]; - - var table = new Tabulator("#tags", { - ajaxURL:baseUrl, - layout:"fitColumns", - columns:columns, - rowClick:function(e, row){ - return false; - }, - ajaxResponse:function(url, params, response){ - - return response.Tags; //return the tableData property of a response json object - }, - }); - } - } ); -}()); diff --git a/js/src/timelines-admin.js b/js/src/timelines-admin.js deleted file mode 100644 index 52bb7a3..0000000 --- a/js/src/timelines-admin.js +++ /dev/null @@ -1,180 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -import Tabulator from 'tabulator-tables'; -require('tabulator-tables/dist/css/tabulator.css'); -import 'select2/dist/js/select2.full.js' -require('select2/dist/css/select2.css'); -require('../../css/style.css'); - -(function() { - - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - function timeConverter(UNIX_timestamp){ - var a = new Date(UNIX_timestamp * 1000); - var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; - var year = a.getFullYear(); - var month = months[a.getMonth()]; - var date = a.getDate(); - var hour = a.getHours(); - var min = a.getMinutes(); - var sec = a.getSeconds(); - var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ; - return time; - } - - $( function() { - - var group1 = "project"; - var group2 = "user"; - var group3 = "day"; - var filterProjectId = ""; - var filterClientId = ""; - - - $(document).ready(function() { - $("#dialog-confirm").dialog({ - autoOpen: false, - modal: true - }); - - - - function editTimeline(dialogTimelineEditForm){ - var target = dialogTimelineEditForm.target; - var form = dialogTimelineEditForm.find( "form" ); - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/edit-timeline/'+target.getData().id); - var jqxhr = $.post( baseUrl, {status:form.find("#status").val()},function() { - getTimelines(); - $(dialogTimelineEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }); - - } - - var dialogTimelineEditForm = $( "#dialog-timeline-edit-form" ).dialog({ - autoOpen: false, - height: 'auto', - width: 'auto', - modal: true, - create: function( event, ui ) { - - }, - buttons: { - "Edit timeline": { text:'Edit timeline', - click:function(){ - editTimeline(dialogTimelineEditForm); - }, class:'primary'}, - Cancel: function() { - dialogTimelineEditForm.dialog( "close" ); - } - }, - close: function() { - - - } - }); - - - - getTimelines(); - - function getTimelines(){ - - var editIcon = function(cell, formatterParams){ //plain text value - return ""; - }; - function pad(n, width, z) { - z = z || '0'; - n = n + ''; - return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; - } - - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/timelines-admin'); - var table = new Tabulator("#timelines", { - ajaxURL:baseUrl, - layout:"fitColumns", - // rowClick:function(e, row){ - // e.preventDefault(); - // dialogTimelineEditForm.target = row; - // debugger; - // dialogTimelineEditForm.find('#status').val(row.getData().status); - // dialogTimelineEditForm.dialog("open"); - // return false; - // }, - columns:[ - //{title:"Id", field:"id", width:100}, //column has a fixed width of 100px; - {title:"#", field:"", formatter:"rownum"}, - {title:"Id", field:"id", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"User", field:"userUid", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Status", field:"status", widthGrow:1}, //column will be allocated 1/5 of the remaining space - - //{title:"User", field:"userUid", widthGrow:1}, //column will be allocated 1/5 of the remaining space - //{title:"Project", field:"projectName", widthGrow:1}, //column will be allocated 1/5 of the remaining space - //{title:"Client", field:"clientName", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"When", field:"timeInterval", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Total Duration", field:"totalDuration",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var duration = cell.getValue(); - var s = Math.floor( (duration) % 60 ); - var m = Math.floor( (duration/60) % 60 ); - var h = Math.floor( (duration/(60*60))); - - return pad(h,2) + ':' + pad(m,2) + ':' + pad(s,2); - - },}, //column will be allocated 1/5 of the remaining space - {title:"created At", field:"createdAt",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var unix = cell.getValue(); - - return timeConverter(unix); - - },}, //column will be allocated 1/5 of the remaining space - {title:"Download", field:"", formatter:"rownum",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/download-timeline/'+cell.getRow().getData()["id"]); - - return ''+"Download"+''; - - }}, - - {formatter:editIcon, width:40, align:"center", cellClick:function(e, cell){ - - dialogTimelineEditForm.target = cell.getRow(); - dialogTimelineEditForm.find('#status').val(cell.getRow().getData().status); - dialogTimelineEditForm.dialog("open"); - return false; - - }}, - - ], - ajaxResponse:function(url, params, response){ - - return response.Timelines; //return the tableData property of a response json object - }, - }); - - } - }); - - - } ); -}()); diff --git a/js/src/timelines.js b/js/src/timelines.js deleted file mode 100644 index 2fe0166..0000000 --- a/js/src/timelines.js +++ /dev/null @@ -1,417 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -// var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -import Tabulator from 'tabulator-tables'; -require('tabulator-tables/dist/css/tabulator.css'); -require("daterangepicker"); -require('daterangepicker/daterangepicker.css'); -import 'select2/dist/js/select2.full.js' -require('select2/dist/css/select2.css'); -require('../../css/style.css'); - -var dtf = require("./dateformat.js"); - -(function() { - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - - $( function() { - - var group1 = "project"; - var group2 = "user"; - var group3 = "day"; - var filterProjectId = ""; - var filterClientId = ""; - - function timeConverter(UNIX_timestamp){ - var a = new Date(UNIX_timestamp * 1000); - var months = ['Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec']; - var year = a.getFullYear(); - var month = months[a.getMonth()]; - var date = a.getDate(); - var hour = a.getHours(); - var min = a.getMinutes(); - var sec = a.getSeconds(); - var time = date + ' ' + month + ' ' + year + ' ' + hour + ':' + min + ':' + sec ; - return time; - } - - $(document).ready(function() { - $("#dialog-confirm").dialog({ - autoOpen: false, - modal: true - }); - - var start = moment().subtract(29, 'days'); - var end = moment(); - function cb(start, end) { - $('#report-range span').html(start.format(dtf.dformat()) + ' - ' + end.format(dtf.dformat())); - } - $("#report-range").daterangepicker({ - timePicker: false, - startDate: start, - endDate: end, - ranges: { - 'Today': [moment(), moment()], - 'Yesterday': [moment().subtract(1, 'days'), moment().subtract(1, 'days')], - 'Last 7 Days': [moment().subtract(6, 'days'), moment()], - 'Last 30 Days': [moment().subtract(29, 'days'), moment()], - 'Last 90 Days': [moment().subtract(89, 'days'), moment()], - 'Last 365 Days': [moment().subtract(364, 'days'), moment()], - 'This Month': [moment().startOf('month'), moment().endOf('month')], - 'Last Month': [moment().subtract(1, 'month').startOf('month'), moment().subtract(1, 'month').endOf('month')], - 'The Month Before Last': [moment().subtract(2, 'month').startOf('month'), moment().subtract(2, 'month').endOf('month')], - 'This Year': [moment().startOf('year'), moment().endOf('year')], - 'Last Year': [moment().subtract(1, 'year').startOf('year'), moment().subtract(1, 'year').endOf('year')], - - }, - locale: { - format: dtf.dformat(), - firstDay: firstDay - } - },cb); - $("#report-range").on('apply.daterangepicker', function(ev, picker) { - start = picker.startDate; - end = picker.endDate; - getReport(); - }); - cb(start, end); - $("#group1").select2(); - $("#group2").select2(); - $("#group3").select2(); - $('#group1').on("select2:select select2:unselect", function(e) { - - group1 = (e.params.data.id != null)? e.params.data.id : ""; - getReport(); - }); - $('#group2').on("select2:select select2:unselect", function(e) { - group2 = (e.params.data.id != null)? e.params.data.id : ""; - getReport(); - }); - $('#group3').on("select2:select select2:unselect", function(e) { - group3 = (e.params.data.id != null)? e.params.data.id : ""; - getReport(); - }); - getReport(); - getTimelines(); - $("#filter-project").select2({ - tags: true, - width: '200px', - escapeMarkup : function(markup) { return markup; }, - placeholder: "Select project", - allowClear: true, - templateResult: function formatState (project) { - var color = '#ffffff'; - if (project.color) { - color = project.color; - } - var $state = $( - '' + project.text + '' - ); - return $state; - }, - ajax: { - tags: true, - url: OC.generateUrl('/apps/timetracker/ajax/projects'), - - dataType: 'json', - delay: 250, - processResults: function (data, page) { //json parse - return { - results: $.map(data.Projects,function(val, i){ - return { id: val.id, text:val.name, color: val.color}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - - }, - }); - - $("#filter-project").on("change", function (e) { - - filterProjectId = ($(e.target).val() != null)? $(e.target).val() : ""; - - getReport(); - }); - - - - $("#filter-client").select2({ - tags: true, - width: '200px', - escapeMarkup : function(markup) { return markup; }, - placeholder: "Select client", - allowClear: true, - ajax: { - tags: true, - url: OC.generateUrl('/apps/timetracker/ajax/clients'), - - dataType: 'json', - delay: 250, - processResults: function (data, page) { //json parse - return { - results: $.map(data.Clients,function(val, i){ - return { id: val.id, text:val.name}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - - }, - }); - - $("#filter-client").on("change", function (e) { - - - filterClientId = ($(e.target).val() != null)? $(e.target).val() : ""; - getReport(); - }); - $('input.select2-input').attr('autocomplete', "xxxxxxxxxxx"); - - - - function getReport(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/report?name=&from='+start.unix()+'&to='+end.unix()+'&group1='+group1+'&group2='+group2+'&timegroup='+group3+'&filterProjectId='+filterProjectId+'&filterClientId='+filterClientId); - function pad(n, width, z) { - z = z || '0'; - n = n + ''; - return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; - } - var table = new Tabulator("#report", { - ajaxURL:baseUrl, - layout:"fitColumns", - columns:[ - //{title:"Id", field:"id", width:100}, //column has a fixed width of 100px; - {title:"#", field:"", formatter:"rownum"}, - {title:"Name", field:"name", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"User", field:"userUid", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Project", field:"project", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Client", field:"client", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"When", field:"time", widthGrow:1, formatter:function(cell, formatterParams, onRendered){ - var t = cell.getValue(); - switch(group3) { - case 'day': - return moment.unix(t).format(dtf.dformat()); - case 'month': - return moment.unix(t).format(dtf.mformat()); - case 'week': - return moment.unix(t).format('YYYY[W]W'); - case 'year': - return moment.unix(t).format('YYYY'); - default: - return moment.unix(t).format(dtf.dtformat()); - } - }}, - {title:"Total Duration", field:"totalDuration",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var duration = cell.getValue(); - var s = Math.floor( (duration) % 60 ); - var m = Math.floor( (duration/60) % 60 ); - var h = Math.floor( (duration/(60*60))); - - return pad(h,2) + ':' + pad(m,2) + ':' + pad(s,2); - - },}, //column will be allocated 1/5 of the remaining space - ], - ajaxResponse:function(url, params, response){ - - return response.items; //return the tableData property of a response json object - }, - }); - $("#timeline-csv").off().click(function(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/timeline'); - $.post(baseUrl, // url - { - from: start.unix(), - to: end.unix(), - group1: group1, - group2: group2, - timegroup: group3, - filterProjectId: filterProjectId, - filterClientId: filterClientId - }, // data to be submit - function(data, status, jqXHR) {// success callback - getTimelines(); - }); - return false; - }); - $("#timeline-csv-email").off().click(function(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/email-timeline'); - $.post(baseUrl, // url - { - from: start.unix(), - to: end.unix(), - group1: group1, - group2: group2, - timegroup: group3, - filterProjectId: filterProjectId, - filterClientId: filterClientId - }, // data to be submit - function(data, status, jqXHR) {// success callback - getTimelines(); - }); - return false; - }); - - } - - - function getTimelines(){ - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/timelines'); - function pad(n, width, z) { - z = z || '0'; - n = n + ''; - return n.length >= width ? n : new Array(width - n.length + 1).join(z) + n; - } - var table = new Tabulator("#timelines", { - ajaxURL:baseUrl, - layout:"fitColumns", - // rowClick:function(e, row){ - // }, - columns:[ - //{title:"Id", field:"id", width:100}, //column has a fixed width of 100px; - {title:"#", field:"", formatter:"rownum"}, - {title:"Id", field:"id", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Status", field:"status", widthGrow:1}, //column will be allocated 1/5 of the remaining space - //{title:"User", field:"userUid", widthGrow:1}, //column will be allocated 1/5 of the remaining space - //{title:"Project", field:"projectName", widthGrow:1}, //column will be allocated 1/5 of the remaining space - //{title:"Client", field:"clientName", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"When", field:"timeInterval", widthGrow:1}, //column will be allocated 1/5 of the remaining space - {title:"Total Duration", field:"totalDuration",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var duration = cell.getValue(); - var s = Math.floor( (duration) % 60 ); - var m = Math.floor( (duration/60) % 60 ); - var h = Math.floor( (duration/(60*60))); - - return pad(h,2) + ':' + pad(m,2) + ':' + pad(s,2); - - },}, //column will be allocated 1/5 of the remaining space - {title:"created At", field:"createdAt",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var unix = cell.getValue(); - - return timeConverter(unix); - - - - },}, //column will be allocated 1/5 of the remaining space - {title:"Download", field:"", formatter:"rownum",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/download-timeline/'+cell.getRow().getData()["id"]); - - return ''+"Download"+''; - - }}, - {title:"Email", field:"", formatter:"rownum",formatter:function(cell, formatterParams, onRendered){ - //cell - the cell component - //formatterParams - parameters set for the column - //onRendered - function to call when the formatter has been rendered - - - return 'Email'; - - },cellClick:function(e, cell){ - $("#dialog-send-email-form").dialog({ - buttons : { - "Confirm" : { - click: function() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/email-timeline/'+cell.getRow().getData().id); - - var jqxhr = $.post( baseUrl, { - email:$('#email-address').val(), - subject:$('#email-subject').val(), - content:$('#email-content').val(), - }, function() { - $("#dialog-send-email-form").dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }, - text: 'Confirm', - class:'primary' - }, - "Cancel" : function() { - $(this).dialog("close"); - } - } - }); - $("#dialog-send-email-form").dialog('open'); - - //cell.getRow().delete(); - } - }, - {formatter:"buttonCross", width:40, align:"center", cellClick:function(e, cell){ - $("#dialog-confirm").dialog({ - buttons : { - "Confirm" : { - click: function() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/delete-timeline/'+cell.getRow().getData().id); - var jqxhr = $.post( baseUrl, function() { - getTimelines(); - $("#dialog-confirm").dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - return false; - }, - text: 'Confirm', - class:'primary' - }, - "Cancel" : function() { - $(this).dialog("close"); - } - } - }); - $("#dialog-confirm").dialog('open'); - - //cell.getRow().delete(); - } - }, - - ], - ajaxResponse:function(url, params, response){ - - return response.Timelines; //return the tableData property of a response json object - }, - }); - - } - }); - - - } ); -}()); diff --git a/js/src/timer.js b/js/src/timer.js deleted file mode 100644 index d8bd201..0000000 --- a/js/src/timer.js +++ /dev/null @@ -1,678 +0,0 @@ -var $ = require("jquery"); -require("jquery-migrate"); -require("daterangepicker"); -var moment = require("moment"); -require("jqueryui"); -//require("jqueryui/jquery-ui.css"); -//import 'select2/dist/js/select2.full.js' -import 'select2/dist/js/select2.full.js' -require('select2/dist/css/select2.css'); -require('daterangepicker/daterangepicker.css'); -require('../../css/style.css'); - -var dtf = require("./dateformat.js"); - -( - - -function() { - - $.ajaxSetup({ - headers: { 'RequestToken': OC.requestToken } - }); - /*select2($);*/ - - - - $( function() { - $('#work-input-form').on('submit', function(e) { - e.preventDefault(); - createWorkItem($(this)); - }); - var days='30'; - var start = moment().startOf('day').subtract(29, 'days'); - var end = moment().endOf('day'); - - function cb(start, end) { - $('#report-range span').html(start.format(dtf.dformat()) + ' - ' + end.format(dtf.dformat())); - } - $("#report-range").daterangepicker({ - timePicker: false, - startDate: start, - endDate: end, - ranges: { - 'Today': [moment().startOf('day'), moment().endOf('day')], - 'Last 7 Days': [moment().startOf('day').subtract(6, 'days'), moment().endOf('day')], - 'Last 30 Days': [moment().startOf('day').subtract(29, 'days'), moment().endOf('day')], - 'Last 90 Days': [moment().startOf('day').subtract(89, 'days'), moment().endOf('day')], - 'Last 365 Days': [moment().startOf('day').subtract(364, 'days'), moment().endOf('day')], - 'This Month': [moment().startOf('month'), moment().endOf('day')], - 'This Year': [moment().startOf('year'), moment().endOf('day')], - 'Starting last year': [moment().startOf('year').subtract(1, 'year'), moment().endOf('day')], - 'Last 3 years': [moment().startOf('day').subtract(3, 'year'), moment().endOf('day')], - 'Last 5 years': [moment().startOf('day').subtract(5, 'year'), moment().endOf('day')], - }, - locale: { - format: dtf.dformat(), - firstDay: firstDay - } - },cb); - $("#report-range").on('apply.daterangepicker', function(ev, picker) { - start = picker.startDate; - end = picker.endDate; - getWorkItems(); - }); - cb(start, end); - - var entityMap = { - '&': '&', - '<': '<', - '>': '>', - '"': '"', - "'": ''', - '/': '/', - '`': '`', - '=': '=' - }; - - function escapeHtml (string) { - return String(string).replace(/[&<>"'`=\/]/g, function (s) { - return entityMap[s]; - }); - } - - getWorkItems(); - var timerInterval; - var dialogWorkItemEditForm = $( "#dialog-work-item-edit-form" ).dialog({ - autoOpen: false, - height: 'auto', - width: 'auto', - modal: true, - buttons: { - "Edit work item": function(){ - editWorkIntem(dialogWorkItemEditForm); - }, - Cancel: function() { - dialogWorkItemEditForm.dialog( "close" ); - } - }, - close: function() { - var form = dialogWorkItemEditForm.find( "form" ); - form[ 0 ].reset(); - } - }); - var picker = $("#hours-manual-entry").daterangepicker({ - timePicker: true, - timePicker24Hour: true, - locale: { - format: dtf.dtformat(), - firstDay: firstDay - } - }); - function validateManualEntryFields(){ - if($('#name-manual-entry').val() == ''){ - $("#confirm-button").button("option", "disabled", true); - } else { - $("#confirm-button").button("option", "disabled", false); - } - } - $('#name-manual-entry').on('input',function() { - - validateManualEntryFields(); - }); - - $("#dialog-manual-entry").dialog({ - autoOpen: false, - buttons : - [ { - id: 'confirm-button', - text: "Confirm", - click: function() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/add-work-interval/'+encodeURIComponent(encodeURIComponent($('#name-manual-entry').val()))); // encode twice so we can have slashes - var jqxhr = $.post( baseUrl, - { - start:picker.data('daterangepicker').startDate.format('DD/MM/YY HH:mm'), - end:picker.data('daterangepicker').endDate.format('DD/MM/YY HH:mm'), - tzoffset: new Date().getTimezoneOffset(), - async: true, - details:$('#details-manual-entry').val()} ,function() { - getWorkItems(); - $("#dialog-manual-entry").dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - }, - }, - { - id: 'cancel-button', - text: "Cancel", - click: function() { - $(this).dialog("close"); - }, - }, - ] - - }); - - $('#manual-entry-button').click(function(e) { - $("#hours-manual-entry").val(''); - $("#dialog-manual-entry").dialog("open"); - return false; - }); - validateManualEntryFields(); - - function editWorkIntem(dialogWorkItemEditForm){ - var target = dialogWorkItemEditForm.target; - var form = dialogWorkItemEditForm.find( "form" ); - var id = $(target).data('myid'); - var baseUrl = OC.generateUrl("/apps/timetracker/ajax/update-work-interval/"+id); - var jqxhr = $.post( baseUrl, {name:form.find("#name").val(),details:form.find("#details").val()},function() { - getWorkItems(); - $(dialogWorkItemEditForm).dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - .always(function() { - - }); - - } - function cutString(s, n){ - if (s.length < n) { - return s; - } - return s.substring(0, n - 4) + ' ...'; - } - function secondsToTimer(s){ - function pad(num, size) { - var s = num+""; - while (s.length < size) s = "0" + s; - return s; - } - var secondsInDay = 60*60*24; - var secondsInHour = 60*60; - var secondsInMinute = 60; - - var days = Math.floor(s/secondsInDay); - var hours = Math.floor((s-days*secondsInDay)/secondsInHour); - var minutes = Math.floor((s-days*secondsInDay-hours*secondsInHour)/secondsInMinute); - var seconds = s % 60; - if (days > 0){ - return days + " days "+pad(hours,2)+':'+pad(minutes,2)+':'+pad(seconds,2); - } else { - return pad(hours,2)+':'+pad(minutes,2)+':'+pad(seconds,2); - } - } - function tsToHour(ts) { - return moment.unix(ts).format(dtf.tformat()); - } - function getWorkItems() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/work-intervals?from='+start.unix()+'&to='+end.unix()+'&tzoffset='+new Date().getTimezoneOffset()); - $.ajaxSetup({ - scriptCharset: "utf-8", - //contentType: "application/json; charset=utf-8" - }); - $.getJSON( baseUrl, function( data ) { - - if (data.running.length > 0){ - localStorage.setItem('isTimerStarted', true); - localStorage.setItem('timerStartTime', data.running[0].start); - var now = Math.floor(Date.now() / 1000); - localStorage.setItem('timerStartTimeLocal', data.running[0].start + now - data.now ); - $('#start-tracking > span').addClass("stop-button").removeClass("play-button"); - timerInterval = setInterval(function() { - if (localStorage.getItem('isTimerStarted') === 'false'){ - clearInterval(timerInterval); - return; - } - var timerStartTimeLocal = localStorage.getItem('timerStartTimeLocal'); - var now = Math.floor(Date.now() / 1000); - - $('#timer').html(secondsToTimer(now - timerStartTimeLocal)); - }, 1000); - } else { - clearInterval(timerInterval); - localStorage.setItem('isTimerStarted', false); - $('#timer').html(secondsToTimer(0)); - $('#start-tracking > span').addClass("play-button").removeClass("stop-button"); - } - - - var days = []; - $.each( data.days, function( dayName, dayMap ) { - - var dayItems = []; - $.each(dayMap, function (dayItemName, workItem){ - var children = []; - - $.each(workItem.children, function (ckey, child){ - var cost = '' - if (child.cost !== 0) { var cost = (child.cost / 100).toFixed(2) } - children.push( - "
  • "+ - "
    "+ - "
    "+ - "
    "+escapeHtml(cutString(child.name,64))+ - "
    "+escapeHtml(cutString(child.details,64))+"
    "+ - "
    "+ - ""+ - ""+ - ""+ - "
    "+ - "
    "+ - tsToHour(child.start)+" - "+((child.running == 1)?'':tsToHour(child.start+child.duration))+ - "
    "+ - "
    "+((child.running == 1)?'running...':secondsToTimer(child.duration))+"
    "+ - "
    "+ - ""+ - "
    "+ - "
    "+ - "
    "+ - "
  • "); - }); - - - dayItems.push("
    "+ - "
      "+ - "
    • "+ - "
      "+ - ((children.length == 1)?"
       
      ":"
      "+children.length+"
      ")+ - "
      "+ - cutString(dayItemName,128)+ - "
      "+ - "
      "+secondsToTimer(workItem.totalTime)+ - "
      "+ - "
      "+ - "
    • "+ - children.join("")+ - "
    "+ - "
    "); - }); - days.push( "
    "+ - "
      "+ - "
    • " + - "
      " + dayName +"
      "+ - dayItems.join("") + - "
    • "+ - "
    "+ - "
    " ); - }); - - $("#work-intervals").html($( "
    ", { - "class": "my-new-list", - html: days.join( "" ) - })); - - $(".cost").focusout(function(e) { - e.preventDefault(); - var input = $(this); - var cost = $(this).val(); - var id = $(e.target).data('myid'); - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/add-cost/' + id); - if (cost !== undefined) { - $.post(baseUrl, {cost: cost}, 'json').done(function (e) { - input.css('border', 'solid 1px green'); - setTimeout(function () { - input.css('border', ''); - }, 3000); - }).fail(function (xhr, status, error) { - var errorMessage = JSON.parse(xhr.responseText); - if (errorMessage.error !== undefined) { - alert(errorMessage.error); - } - input.css('border', 'solid 1px red'); - }); - } - }); - - $(".wi-child-hours").each(function(){ - $(this).daterangepicker({ - timePicker: true, - startDate:moment.unix($(this).data('start-date')).format(dtf.dtformat()), - endDate:moment.unix($(this).data('end-date')).format(dtf.dtformat()), - timePicker24Hour: true, - locale: { - format: dtf.dtformat(), - firstDay: firstDay - } - }); - - $(this).on('apply.daterangepicker', function(ev, picker) { - var id = $(this).data('myid'); - var jqxhr = $.post( "ajax/update-work-interval/"+id,{start:picker.startDate.format('DD/MM/YY HH:mm'), end:picker.endDate.format('DD/MM/YY HH:mm'), tzoffset: new Date().getTimezoneOffset()}, function() { - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - getWorkItems(); - }) - .fail(function() { - alert( "error" ); - }) - .always(function() { - }); - }); - }); - $('.wi-child-name').click(function(e) { - e.preventDefault(); - dialogWorkItemEditForm.target = e.target; - - var form = dialogWorkItemEditForm.find( "form" ) - form.find("#name").val($(e.target).data("name")); - form.find("#details").val($(e.target).data("details")); - dialogWorkItemEditForm.dialog("open"); - return false; - - }) - $('.wi-play').click(function(e) { - e.preventDefault(); - createWorkItem($(this)); - }); - - $('.wi-resume').click(function(e) { - e.preventDefault(); - resumeWorkItem($(this)); - }); - $('.wi-trash').click(function(e) { - $("#dialog-confirm").dialog({ - buttons : { - "Confirm" : function() { - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/delete-work-interval/'+e.target.id); - var jqxhr = $.post( baseUrl, function() { - getWorkItems(); - $("#dialog-confirm").dialog("close"); - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - }) - .fail(function() { - alert( "error" ); - }) - }, - "Cancel" : function() { - $(this).dialog("close"); - } - } - }); - $("#dialog-confirm").dialog("open"); - return false; - }); - - var projectsAjaxUrl = OC.generateUrl('/apps/timetracker/ajax/projects'); - $(".set-project").each(function(){ - //var interval = setInterval( function() { - - var id = $(this).data('myid'); - var projectId = $(this).data('projectid'); - var projectColor = $(this).data('projectcolor'); - - $(this).select2({ - containerCssClass:'project-select', - escapeMarkup : function(markup) { return markup; }, - placeholder: "", - allowClear: true, - templateResult: function formatState (project) { - var color = '#ffffff'; - if (project.color) { - color = project.color; - } - var $state = $( - '' + project.text + '' - ); - return $state; - }, - templateSelection: function formatState (project) { - var color = '#ffffff'; - if (projectColor) { - color = projectColor; - } - var $state = $( - '' + project.text + '' - ); - return $state; - }, - ajax: { - url: projectsAjaxUrl, - - dataType: 'json', - delay: 250, - processResults: function (data) { //json parse - return { - results: $.map(data.Projects,function(val, i){ - return { id: val.id, text:val.name, color: val.color}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - - }, - }); - $(this).data('myid',id); - - $(this).val(projectId).trigger('change'); - //clearInterval(interval); - //}.bind(this),0); - }); - - var tagsAjaxUrl = OC.generateUrl('/apps/timetracker/ajax/tags'); - $(".set-tag").each(function(){ - //var interval = setInterval( function() { - - - $(this).select2({ - tags: true, - containerCssClass:'tags-select', - placeholder: "Select tags...", - allowClear: true, - - ajax: { - url: function () { return tagsAjaxUrl+'?workItem='+$(this).data('myid');}, - data: function (params){ - var query = { - q: params.term, - type: 'public' - } - - // Query parameters will be ?search=[term]&type=public - return query; - }, - headers: { 'RequestToken': OC.requestToken }, - formatNoMatches: function() { - return ''; - }, - dataType: 'json', - delay: 250, - processResults: function (data) { //json parse - return { - results: $.map(data.Tags,function(val, i){ - return { id: val.id, text:val.name}; - }), - pagination: { - more: false, - } - }; - }, - cache: false, - }, - }); - $(this).select2('val', []); - //clearInterval(interval); - //}.bind(this),0); - }); - $('input.select2-input').attr('autocomplete', "xxxxxxxxxxx") - - //$(".set-project").on("change", function (e) { - $(".set-project").on("select2:select select2:unselect", function (e) { - var myid = $(e.target).data('myid'); - var selectedId = $(e.target).val(); - var jqxhr = $.post( "ajax/update-work-interval/"+myid,{projectId:selectedId}, function() { - - - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - getWorkItems(); - }) - .fail(function() { - alert( "error" ); - }) - .always(function() { - }); - }); - $(".set-project").on("select2:unselecting", function(e) { - var self = $(this); - setTimeout(function() { - self.select2('close'); - }, 0); - }); - - $(".set-tag").on("change", function (e) { - var myid = $(e.target).data('myid'); - var selectedTag = $(e.target).val(); - var jqxhr = $.post( "ajax/update-work-interval/"+myid,{tagId:selectedTag.join(",")}, function() { - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } - getWorkItems(); - }) - .fail(function() { - alert( "error" ); - }) - .always(function() { - }); - }); - $(".set-tag").on("select2:unselecting", function(e) { - var self = $(this); - setTimeout(function() { - self.select2('close'); - }, 0); - }); - }).fail(function() { - alert( "error getting work items" ); - }); - } - - function createWorkItem(wiPlay) { - var workName = $('#work-input').val(); - $('#work-input').val(wiPlay.data('work-name')); - startTimer(wiPlay.data('projectid'), wiPlay.data('tagids'), workName); - return false; - } - - function resumeWorkItem(wiResume) { - startTimer(wiResume.data('projectid'), wiResume.data('tagids'), wiResume.data('work-name')); - return false; - } - - function startTimer(projectId = null, tags = "", inputWorkName = null){ - if(localStorage.getItem('isTimerStarted') === 'true'){ - stopTimer(startTimer, [projectId, tags, inputWorkName]); - return; - } - var workName = inputWorkName ?? $('#work-input').val(); - if (workName == ''){ - workName = 'no description'; - } - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/start-timer/'+encodeURIComponent(encodeURIComponent(workName))); - var jqxhr = $.post(baseUrl, { projectId: projectId, tags: tags}, function() { - }) - .done(function(data, status, jqxhr) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } else { - localStorage.setItem('isTimerStarted', true); - $('#start-tracking > span').addClass("stop-button").removeClass("play-button"); - } - }) - .fail(function() { - alert( "error" ); - }).always(function() { - getWorkItems(); - }); - - } - function stopTimer(onStopped = null, args = []){ - - var workName = $('#work-input').val(); - if (workName == ''){ - workName = 'no description'; - } - var baseUrl = OC.generateUrl('/apps/timetracker/ajax/stop-timer/'+encodeURIComponent(encodeURIComponent(workName))); - var jqxhr = $.post(baseUrl, function() { // encode twice so we can pass / character - }) - .done(function(data, status, jqXHR) { - var response = data; - if ('Error' in response){ - alert(response.Error); - } else { - localStorage.setItem('isTimerStarted', false); - $('#start-tracking > span').addClass("play-button").removeClass("stop-button"); - if (onStopped != null){ - onStopped(...args); - } else { - getWorkItems(); - } - } - }) - .fail(function() { - alert( "error" ); - }) - .always(function() { - - }); - } - - - - $( "#datepicker-from" ).datepicker(); - $( "#datepicker-to" ).datepicker(); - - if(localStorage.getItem('isTimerStarted') === 'true'){ - $('#start-tracking > span').addClass("stop-button").removeClass("play-button"); - } else { - $('#start-tracking > span').addClass("play-button").removeClass("stop-button"); - } - $( "#start-tracking" ).click(function() { - if(localStorage.getItem('isTimerStarted') === 'true'){ - stopTimer(); - } else { - startTimer(); - } - return false; - }); - } ); - -}()); diff --git a/js/webpack.config.js b/js/webpack.config.js index 0696cbf..9b9247c 100644 --- a/js/webpack.config.js +++ b/js/webpack.config.js @@ -10,25 +10,11 @@ module.exports = { //mode: 'development', devtool: 'cheap-module-source-map', entry: { - timer: './src/timer.js', - clients: './src/clients.js', - dashboard: './src/dashboard.js', - projects: './src/projects.js', - reports: './src/reports.js', - tags: './src/tags.js', - goals: './src/goals.js', - timelines: './src/timelines.js', - timelinesadmin: './src/timelines-admin.js', app: './src/app/app.js', }, output: { filename: '[name].js', path: __dirname + '/dist' - }, - resolve: { - alias: { - 'jquery-ui': 'jqueryui' - } }, module: { rules: [ diff --git a/lib/Controller/ClientsController.php b/lib/Controller/ClientsController.php index fee8296..3375ba1 100644 --- a/lib/Controller/ClientsController.php +++ b/lib/Controller/ClientsController.php @@ -26,7 +26,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/clients', 'script' => 'dist/clients']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/DashboardController.php b/lib/Controller/DashboardController.php index 6b1f841..9cc4adb 100644 --- a/lib/Controller/DashboardController.php +++ b/lib/Controller/DashboardController.php @@ -25,7 +25,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/dashboard', 'script' => 'dist/dashboard']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/GoalsController.php b/lib/Controller/GoalsController.php index 514df91..a625fb5 100644 --- a/lib/Controller/GoalsController.php +++ b/lib/Controller/GoalsController.php @@ -25,7 +25,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/goals', 'script' => 'dist/goals']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index df3917e..eee61a0 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -26,15 +26,6 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/index', 'script' => 'dist/timer']); // templates/index.php - } - - /** - * - * @NoAdminRequired - * @NoCSRFRequired - */ - public function spa($path = '') { return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/ProjectsController.php b/lib/Controller/ProjectsController.php index 25eae3b..c15f32e 100644 --- a/lib/Controller/ProjectsController.php +++ b/lib/Controller/ProjectsController.php @@ -30,7 +30,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/projects', 'script' => 'dist/projects']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/ReportsController.php b/lib/Controller/ReportsController.php index e2e8fc5..0cfb1f9 100644 --- a/lib/Controller/ReportsController.php +++ b/lib/Controller/ReportsController.php @@ -25,7 +25,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/reports', 'script' => 'dist/reports']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/TagsController.php b/lib/Controller/TagsController.php index 95cdc1b..4f24f29 100644 --- a/lib/Controller/TagsController.php +++ b/lib/Controller/TagsController.php @@ -25,7 +25,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/tags', 'script' => 'dist/tags']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/TimelinesAdminController.php b/lib/Controller/TimelinesAdminController.php index 3f414b7..99c8122 100644 --- a/lib/Controller/TimelinesAdminController.php +++ b/lib/Controller/TimelinesAdminController.php @@ -25,7 +25,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/timelines-admin', 'script' => 'dist/timelinesadmin']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/lib/Controller/TimelinesController.php b/lib/Controller/TimelinesController.php index 62bbfeb..e1fab0d 100644 --- a/lib/Controller/TimelinesController.php +++ b/lib/Controller/TimelinesController.php @@ -25,7 +25,7 @@ public function __construct($AppName, IRequest $request, IUserSession $userSessi * @NoCSRFRequired */ public function index() { - return new TemplateResponse('timetracker', 'index',['appPage' => 'content/timelines', 'script' => 'dist/timelines']); // templates/index.php + return new TemplateResponse('timetracker', 'spa', ['script' => 'dist/app']); // templates/spa.php } diff --git a/templates/content/clients.php b/templates/content/clients.php deleted file mode 100644 index e0f12ac..0000000 --- a/templates/content/clients.php +++ /dev/null @@ -1,28 +0,0 @@ -
    -

    Clients

    -
    -
    - - -
    -
    - - -
    -
    -
    -
    \ No newline at end of file diff --git a/templates/content/dashboard.php b/templates/content/dashboard.php deleted file mode 100644 index a693b02..0000000 --- a/templates/content/dashboard.php +++ /dev/null @@ -1,22 +0,0 @@ -
    -

    Dashboard

    - - -
    -
    -
    -

    Time (in minutes) allocated to each client in the last days

    -
    -
    -
    -
    -   - -
    -
    - - -
    -
    -
    -
    diff --git a/templates/content/goals.php b/templates/content/goals.php deleted file mode 100644 index b0f4159..0000000 --- a/templates/content/goals.php +++ /dev/null @@ -1,26 +0,0 @@ -
    -

    Goals

    -
    -
    - - - - -
    -
    - -
    -
    -
    -
    \ No newline at end of file diff --git a/templates/content/index.php b/templates/content/index.php deleted file mode 100644 index 06b42b8..0000000 --- a/templates/content/index.php +++ /dev/null @@ -1,69 +0,0 @@ -
    -
    -
    -
    - -
    -
    -
    -
    - -
    - -
    -
    Manual entry
    - - - - - -
    -
    -
    -
    -   - -
    -
    -
    - -
    -
    -
    -
    diff --git a/templates/content/projects.php b/templates/content/projects.php deleted file mode 100644 index 4569291..0000000 --- a/templates/content/projects.php +++ /dev/null @@ -1,81 +0,0 @@ -
    -

    Projects

    -
    -
    - - - -
    - -
    -
    -
    - - -
    -
    -
    - -
    - -
    - -
    - - -
    - -
    -
    -
    \ No newline at end of file diff --git a/templates/content/reports.php b/templates/content/reports.php deleted file mode 100644 index a2950cc..0000000 --- a/templates/content/reports.php +++ /dev/null @@ -1,79 +0,0 @@ -
    -

    Reports

    - - - -
    -
    -
    -
    -   - -
    -
    -
    -
    - - - - -
    -
    - - -
    -
    - - - -
    - -
    -
    -
    \ No newline at end of file diff --git a/templates/content/tags.php b/templates/content/tags.php deleted file mode 100644 index 10e6823..0000000 --- a/templates/content/tags.php +++ /dev/null @@ -1,28 +0,0 @@ -
    -

    Tags

    -
    -
    - - -
    -
    - - -
    -
    -
    -
    \ No newline at end of file diff --git a/templates/content/timelines-admin.php b/templates/content/timelines-admin.php deleted file mode 100644 index e16f4ca..0000000 --- a/templates/content/timelines-admin.php +++ /dev/null @@ -1,43 +0,0 @@ -
    -

    Timelines Admin

    - - - -
    -
    - - -
    -
    -
    \ No newline at end of file diff --git a/templates/content/timelines.php b/templates/content/timelines.php deleted file mode 100644 index 73ea6f4..0000000 --- a/templates/content/timelines.php +++ /dev/null @@ -1,102 +0,0 @@ -
    -

    Timelines

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

    Exported Timelines Statuses

    -
    -
    -
    -
    \ No newline at end of file diff --git a/templates/index.php b/templates/index.php deleted file mode 100644 index 7d8ef7d..0000000 --- a/templates/index.php +++ /dev/null @@ -1,23 +0,0 @@ -= 28) { - style('timetracker', 'style-compat'); -} - -script('timetracker', $script); - -?> - -
    - inc('navigation/index')); ?> -
    - -
    -
    - inc($appPage)); ?> -
    -
    diff --git a/templates/navigation/index.php b/templates/navigation/index.php deleted file mode 100644 index 7c2f770..0000000 --- a/templates/navigation/index.php +++ /dev/null @@ -1,15 +0,0 @@ -get(\OCP\IURLGenerator::class); ?> - From 8adf115c3df474062a3aaf701acbded8a3a86763 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 13 Jul 2026 00:26:32 +0200 Subject: [PATCH 08/12] Fix cramped Manual Entry modal in Timer view The date pickers were rendered inline within the modal's own scroll area, so opening either calendar pushed content down and required scrolling to see it. Set the modal to NcModal's "normal" size and let both pickers teleport their calendar to (append-to-body) so it floats above the modal instead of being clipped by it. Co-Authored-By: Claude Sonnet 5 --- appinfo/info.xml | 2 +- js/src/app/views/TimerView.vue | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index 61780a9..8d61743 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -35,7 +35,7 @@ Mit dem integrierten Dashboard lässt sich anhand eines Kuchen-/Donut-Diagramms Diese App wird aktuell noch weiterentwickelt, also: Augen offen halten für neue Features! Und falls Dir irgendwelche Verbesserungsvorschläge, Probleme oder neue Features einfallen, schau mal auf unserem [GitHub Projekt](https://github.com/mtierltd/timetracker) vorbei, vielleicht wird Dein Thema bereits diskutiert! Und falls nicht, starte gerne eine neue Diskussion, wir freuen uns auf Dein Feedback! - 0.0.88 + 0.0.89 agpl MTier Ltd. TimeTracker diff --git a/js/src/app/views/TimerView.vue b/js/src/app/views/TimerView.vue index fdd0a0e..1a8d6a6 100644 --- a/js/src/app/views/TimerView.vue +++ b/js/src/app/views/TimerView.vue @@ -93,13 +93,13 @@
    - +

    Manual entry

    - - + + Add entry
    From fd18ca8df7b7ccd171a18909964a3a9b77e804fe Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 13 Jul 2026 00:35:24 +0200 Subject: [PATCH 09/12] Restore date range presets on Timer, Dashboard, Reports and Timelines The old daterangepicker library bundled preset shortcuts (Today, Last 7/30/90/365 days, This/Last Month, This/Last Year); replacing it with plain from/to NcDateTimePicker fields during the Vue migration dropped that shortcut entirely rather than reimplementing it. Adds a shared dateRangePresets.js helper and a "Quick range..." select on all four views that had a date range, restoring the jump-to-range behavior. Co-Authored-By: Claude Sonnet 5 --- appinfo/info.xml | 2 +- js/src/app/dateRangePresets.js | 76 ++++++++++++++++++++++++++++++ js/src/app/views/DashboardView.vue | 16 +++++++ js/src/app/views/ReportsView.vue | 13 +++++ js/src/app/views/TimelinesView.vue | 13 +++++ js/src/app/views/TimerView.vue | 16 +++++++ 6 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 js/src/app/dateRangePresets.js diff --git a/appinfo/info.xml b/appinfo/info.xml index 8d61743..cfa7620 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -35,7 +35,7 @@ Mit dem integrierten Dashboard lässt sich anhand eines Kuchen-/Donut-Diagramms Diese App wird aktuell noch weiterentwickelt, also: Augen offen halten für neue Features! Und falls Dir irgendwelche Verbesserungsvorschläge, Probleme oder neue Features einfallen, schau mal auf unserem [GitHub Projekt](https://github.com/mtierltd/timetracker) vorbei, vielleicht wird Dein Thema bereits diskutiert! Und falls nicht, starte gerne eine neue Diskussion, wir freuen uns auf Dein Feedback! - 0.0.89 + 0.0.90 agpl MTier Ltd. TimeTracker diff --git a/js/src/app/dateRangePresets.js b/js/src/app/dateRangePresets.js new file mode 100644 index 0000000..236e6d9 --- /dev/null +++ b/js/src/app/dateRangePresets.js @@ -0,0 +1,76 @@ +export const DATE_RANGE_PRESETS = [ + { key: 'today', label: 'Today' }, + { key: 'yesterday', label: 'Yesterday' }, + { key: 'last7', label: 'Last 7 days' }, + { key: 'last30', label: 'Last 30 days' }, + { key: 'last90', label: 'Last 90 days' }, + { key: 'last365', label: 'Last 365 days' }, + { key: 'thisMonth', label: 'This month' }, + { key: 'lastMonth', label: 'Last month' }, + { key: 'thisYear', label: 'This year' }, + { key: 'lastYear', label: 'Last year' }, +] + +function startOfDay(d) { + const x = new Date(d) + x.setHours(0, 0, 0, 0) + return x +} +function endOfDay(d) { + const x = new Date(d) + x.setHours(23, 59, 59, 999) + return x +} + +export function getPresetRange(key) { + const now = new Date() + switch (key) { + case 'today': + return { from: startOfDay(now), to: endOfDay(now) } + case 'yesterday': { + const y = new Date(now) + y.setDate(y.getDate() - 1) + return { from: startOfDay(y), to: endOfDay(y) } + } + case 'last7': { + const from = new Date(now) + from.setDate(from.getDate() - 6) + return { from: startOfDay(from), to: endOfDay(now) } + } + case 'last30': { + const from = new Date(now) + from.setDate(from.getDate() - 29) + return { from: startOfDay(from), to: endOfDay(now) } + } + case 'last90': { + const from = new Date(now) + from.setDate(from.getDate() - 89) + return { from: startOfDay(from), to: endOfDay(now) } + } + case 'last365': { + const from = new Date(now) + from.setDate(from.getDate() - 364) + return { from: startOfDay(from), to: endOfDay(now) } + } + case 'thisMonth': { + const from = new Date(now.getFullYear(), now.getMonth(), 1) + return { from: startOfDay(from), to: endOfDay(now) } + } + case 'lastMonth': { + const from = new Date(now.getFullYear(), now.getMonth() - 1, 1) + const to = new Date(now.getFullYear(), now.getMonth(), 0) + return { from: startOfDay(from), to: endOfDay(to) } + } + case 'thisYear': { + const from = new Date(now.getFullYear(), 0, 1) + return { from: startOfDay(from), to: endOfDay(now) } + } + case 'lastYear': { + const from = new Date(now.getFullYear() - 1, 0, 1) + const to = new Date(now.getFullYear() - 1, 11, 31) + return { from: startOfDay(from), to: endOfDay(to) } + } + default: + return null + } +} diff --git a/js/src/app/views/DashboardView.vue b/js/src/app/views/DashboardView.vue index f2ecf65..da4ad6e 100644 --- a/js/src/app/views/DashboardView.vue +++ b/js/src/app/views/DashboardView.vue @@ -4,6 +4,10 @@

    Dashboard

    + to @@ -38,6 +42,7 @@ import NcAppContent from '@nextcloud/vue/components/NcAppContent' import NcButton from '@nextcloud/vue/components/NcButton' import NcDateTimePicker from '@nextcloud/vue/components/NcDateTimePicker' import { apiGet } from '../api.js' +import { DATE_RANGE_PRESETS, getPresetRange } from '../dateRangePresets.js' ChartJS.register(ArcElement, Tooltip, Legend) @@ -54,6 +59,7 @@ export default { return { rangeFrom: from, rangeTo: now, + presets: DATE_RANGE_PRESETS, items: [], } }, @@ -127,6 +133,13 @@ export default { const m = Math.floor((seconds % 3600) / 60) return `${h} hours ${m} minutes` }, + applyPreset(key) { + const range = getPresetRange(key) + if (!range) return + this.rangeFrom = range.from + this.rangeTo = range.to + this.loadReport() + }, async loadReport() { const data = await apiGet('/report', { name: '', @@ -154,6 +167,9 @@ export default { gap: 8px; padding-bottom: 16px; } +.native-select { + height: 34px; +} .summary { font-weight: bold; margin-bottom: 20px; diff --git a/js/src/app/views/ReportsView.vue b/js/src/app/views/ReportsView.vue index 67681d1..65021a1 100644 --- a/js/src/app/views/ReportsView.vue +++ b/js/src/app/views/ReportsView.vue @@ -28,6 +28,10 @@
    + to @@ -80,6 +84,7 @@ import NcButton from '@nextcloud/vue/components/NcButton' import NcSelect from '@nextcloud/vue/components/NcSelect' import NcDateTimePicker from '@nextcloud/vue/components/NcDateTimePicker' import { apiGet } from '../api.js' +import { DATE_RANGE_PRESETS, getPresetRange } from '../dateRangePresets.js' function pad(n) { return String(n).padStart(2, '0') @@ -110,6 +115,7 @@ export default { timegroup: 'day', rangeFrom: from, rangeTo: now, + presets: DATE_RANGE_PRESETS, } }, computed: { @@ -138,6 +144,13 @@ export default { const data = await apiGet('/clients') this.clients = data.Clients || [] }, + applyPreset(key) { + const range = getPresetRange(key) + if (!range) return + this.rangeFrom = range.from + this.rangeTo = range.to + this.loadReport() + }, async loadReport() { const data = await apiGet('/report', { name: '', diff --git a/js/src/app/views/TimelinesView.vue b/js/src/app/views/TimelinesView.vue index 9bab9f5..9f6b949 100644 --- a/js/src/app/views/TimelinesView.vue +++ b/js/src/app/views/TimelinesView.vue @@ -23,6 +23,10 @@
    + to @@ -124,6 +128,7 @@ import NcModal from '@nextcloud/vue/components/NcModal' import { showError, showSuccess } from '@nextcloud/dialogs' import { generateUrl } from '@nextcloud/router' import { apiGet, apiPost } from '../api.js' +import { DATE_RANGE_PRESETS, getPresetRange } from '../dateRangePresets.js' function pad(n) { return String(n).padStart(2, '0') @@ -155,6 +160,7 @@ export default { timegroup: 'day', rangeFrom: from, rangeTo: now, + presets: DATE_RANGE_PRESETS, emailing: null, emailForm: { email: '', subject: '', content: '' }, confirmVisible: false, @@ -198,6 +204,13 @@ export default { const data = await apiGet('/report', this.reportParams()) this.items = data.items || [] }, + applyPreset(key) { + const range = getPresetRange(key) + if (!range) return + this.rangeFrom = range.from + this.rangeTo = range.to + this.loadReport() + }, async exportTimeline() { try { await apiPost('/timeline', this.reportParams()) diff --git a/js/src/app/views/TimerView.vue b/js/src/app/views/TimerView.vue index 1a8d6a6..ef2cab2 100644 --- a/js/src/app/views/TimerView.vue +++ b/js/src/app/views/TimerView.vue @@ -11,6 +11,10 @@
    + to @@ -116,6 +120,7 @@ import NcDialog from '@nextcloud/vue/components/NcDialog' import NcModal from '@nextcloud/vue/components/NcModal' import { showError } from '@nextcloud/dialogs' import { apiGet, apiPost } from '../api.js' +import { DATE_RANGE_PRESETS, getPresetRange } from '../dateRangePresets.js' function pad(n) { return String(n).padStart(2, '0') @@ -143,6 +148,7 @@ export default { tags: [], rangeFrom: from, rangeTo: now, + presets: DATE_RANGE_PRESETS, liveTimerText: '00:00:00', liveTimerInterval: null, editingItem: null, @@ -190,6 +196,13 @@ export default { const data = await apiGet('/tags') this.tags = data.Tags || [] }, + applyPreset(key) { + const range = getPresetRange(key) + if (!range) return + this.rangeFrom = range.from + this.rangeTo = range.to + this.loadWorkIntervals() + }, async loadWorkIntervals() { const data = await apiGet('/work-intervals', { from: Math.floor(this.rangeFrom.getTime() / 1000), @@ -360,6 +373,9 @@ export default { gap: 8px; padding-bottom: 20px; } +.native-select { + height: 34px; +} .day-group { margin-bottom: 24px; } From 706c2ace88a87b2c3d8c9e65182e1ce9e7f540b3 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Mon, 13 Jul 2026 07:54:03 +0200 Subject: [PATCH 10/12] Update PageControllerTest for the SPA template cutover PageController::index() now renders the 'spa' template (Stage 4 of the frontend migration) instead of 'index'; the test still asserted the old template name and was failing in CI as a result. Co-Authored-By: Claude Sonnet 5 --- tests/Unit/Controller/PageControllerTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Controller/PageControllerTest.php b/tests/Unit/Controller/PageControllerTest.php index 1c51594..c6c8627 100644 --- a/tests/Unit/Controller/PageControllerTest.php +++ b/tests/Unit/Controller/PageControllerTest.php @@ -28,7 +28,7 @@ public function setUp(): void { public function testIndex(): void { $result = $this->controller->index(); - $this->assertEquals('index', $result->getTemplateName()); + $this->assertEquals('spa', $result->getTemplateName()); $this->assertInstanceOf(TemplateResponse::class, $result); } From 8ab7b07c0a64fdb770f4e257f9fd3951851f02f2 Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 14 Jul 2026 08:05:44 +0200 Subject: [PATCH 11/12] Restore inline start/end time editing on Timer entries The legacy UI let you click an entry's duration to open an inline date-range picker and adjust its start/end time directly, posting to the same update-work-interval endpoint used for manual entries. This was dropped during the Vue migration along with the rest of that row's inline editors. Adds an "Edit time" modal (two NcDateTimePicker fields) triggered by clicking the Duration cell, reusing the same date-formatting helper as the manual entry form. Co-Authored-By: Claude Sonnet 5 --- appinfo/info.xml | 2 +- js/src/app/views/TimerView.vue | 53 +++++++++++++++++++++++++++------- 2 files changed, 43 insertions(+), 12 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index cfa7620..689673f 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -35,7 +35,7 @@ Mit dem integrierten Dashboard lässt sich anhand eines Kuchen-/Donut-Diagramms Diese App wird aktuell noch weiterentwickelt, also: Augen offen halten für neue Features! Und falls Dir irgendwelche Verbesserungsvorschläge, Probleme oder neue Features einfallen, schau mal auf unserem [GitHub Projekt](https://github.com/mtierltd/timetracker) vorbei, vielleicht wird Dein Thema bereits diskutiert! Und falls nicht, starte gerne eine neue Diskussion, wir freuen uns auf Dein Feedback! - 0.0.90 + 0.0.91 agpl MTier Ltd. TimeTracker diff --git a/js/src/app/views/TimerView.vue b/js/src/app/views/TimerView.vue index ef2cab2..72c2496 100644 --- a/js/src/app/views/TimerView.vue +++ b/js/src/app/views/TimerView.vue @@ -63,7 +63,7 @@ style="min-width: 160px;" @update:model-value="(t) => updateTags(item, t)" /> - {{ formatDuration(item.duration) }} + {{ formatDuration(item.duration) }} + +
    +

    Edit time

    + + + Save +
    +
    +

    Manual entry

    @@ -132,6 +141,14 @@ function formatDuration(seconds) { const s = seconds % 60 return `${pad(h)}:${pad(m)}:${pad(s)}` } +function formatForApi(d) { + const dd = String(d.getDate()).padStart(2, '0') + const mm = String(d.getMonth() + 1).padStart(2, '0') + const yy = String(d.getFullYear()).slice(-2) + const h = String(d.getHours()).padStart(2, '0') + const mi = String(d.getMinutes()).padStart(2, '0') + return `${dd}/${mm}/${yy} ${h}:${mi}` +} export default { name: 'TimerView', @@ -153,6 +170,8 @@ export default { liveTimerInterval: null, editingItem: null, editForm: { name: '', details: '' }, + editingTimeItem: null, + timeForm: { start: null, end: null }, manualEntryVisible: false, manualForm: { name: '', details: '', start: null, end: null }, confirmVisible: false, @@ -303,19 +322,31 @@ export default { this.manualForm = { name: '', details: '', start: now, end: now } this.manualEntryVisible = true }, - async saveManualEntry() { - const fmt = (d) => { - const dd = String(d.getDate()).padStart(2, '0') - const mm = String(d.getMonth() + 1).padStart(2, '0') - const yy = String(d.getFullYear()).slice(-2) - const h = String(d.getHours()).padStart(2, '0') - const mi = String(d.getMinutes()).padStart(2, '0') - return `${dd}/${mm}/${yy} ${h}:${mi}` + openEditTime(item) { + this.editingTimeItem = item + this.timeForm = { + start: new Date(item.start * 1000), + end: new Date((item.start + item.duration) * 1000), + } + }, + async saveEditTime() { + try { + await apiPost(`/update-work-interval/${this.editingTimeItem.id}`, { + start: formatForApi(this.timeForm.start), + end: formatForApi(this.timeForm.end), + tzoffset: new Date().getTimezoneOffset(), + }) + this.editingTimeItem = null + await this.loadWorkIntervals() + } catch (e) { + showError(e.message) } + }, + async saveManualEntry() { try { await apiPost(`/add-work-interval/${encodeURIComponent(encodeURIComponent(this.manualForm.name))}`, { - start: fmt(this.manualForm.start), - end: fmt(this.manualForm.end), + start: formatForApi(this.manualForm.start), + end: formatForApi(this.manualForm.end), tzoffset: new Date().getTimezoneOffset(), details: this.manualForm.details, }) From a841648354eec1f6e00f74c52c387aac1853a4bd Mon Sep 17 00:00:00 2001 From: Martin Zeitler Date: Tue, 14 Jul 2026 09:15:53 +0200 Subject: [PATCH 12/12] Restore more functionality dropped during the Vue migration MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up audit against the legacy jQuery implementation found three more gaps beyond the manual-entry and date-preset fixes already made: - Timer: the per-row cost field posted to the backend on every keystroke instead of on blur, and lost the success/error visual feedback the old jQuery version had. Now uses a local draft value committed on blur, with NcTextField's native success/error state. - Timer: the per-row tag picker lost the "type a new tag name inline" behavior (select2's tags:true). Restored via NcSelect's taggable/push-tags, matching updateWorkInterval's existing support for creating a tag on the fly from a non-numeric value. (Checked Projects' "Allowed tags" picker for the same gap, but its backend path, TagMapper::allowedTags(), has no such tag-creation logic — so enabling taggable there would insert a broken/orphaned row rather than restore a working feature. Left as-is.) - Dashboard: the two charts silently dropped the client dimension, showing only project-level totals even though the backend groups by client+project. Chart labels are now "Client / Project" so nothing is collapsed together. Also added the "Ended" column to Reports' CSV export (present in the original, computed from time+totalDuration or '*' when grouped) and fixed the CSV's "When" column to use the same formatted value as the on-screen table instead of a raw unix timestamp. Co-Authored-By: Claude Sonnet 5 --- appinfo/info.xml | 2 +- js/src/app/views/DashboardView.vue | 18 ++++++++++-------- js/src/app/views/ReportsView.vue | 11 ++++++++--- js/src/app/views/TimerView.vue | 24 ++++++++++++++++++++---- 4 files changed, 39 insertions(+), 16 deletions(-) diff --git a/appinfo/info.xml b/appinfo/info.xml index 689673f..d5e44ef 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -35,7 +35,7 @@ Mit dem integrierten Dashboard lässt sich anhand eines Kuchen-/Donut-Diagramms Diese App wird aktuell noch weiterentwickelt, also: Augen offen halten für neue Features! Und falls Dir irgendwelche Verbesserungsvorschläge, Probleme oder neue Features einfallen, schau mal auf unserem [GitHub Projekt](https://github.com/mtierltd/timetracker) vorbei, vielleicht wird Dein Thema bereits diskutiert! Und falls nicht, starte gerne eine neue Diskussion, wir freuen uns auf Dein Feedback! - 0.0.91 + 0.0.92 agpl MTier Ltd. TimeTracker diff --git a/js/src/app/views/DashboardView.vue b/js/src/app/views/DashboardView.vue index da4ad6e..d903ef4 100644 --- a/js/src/app/views/DashboardView.vue +++ b/js/src/app/views/DashboardView.vue @@ -21,12 +21,12 @@
    -

    Time by project

    +

    Time by client / project

    No data to display

    -

    Cost by project

    +

    Cost by client / project

    No data to display

    @@ -70,10 +70,12 @@ export default { totalCost() { return this.items.reduce((sum, i) => sum + (i.cost || 0), 0) }, - byProject() { + byClientProject() { const map = new Map() for (const item of this.items) { - const key = item.project || 'Project Not Set' + const client = item.client || 'Client Not Set' + const project = item.project || 'Project Not Set' + const key = `${client} / ${project}` if (!map.has(key)) map.set(key, { duration: 0, cost: 0 }) const entry = map.get(key) entry.duration += item.totalDuration || 0 @@ -82,21 +84,21 @@ export default { return map }, timeChartData() { - const labels = [...this.byProject.keys()] + const labels = [...this.byClientProject.keys()] return { labels, datasets: [{ - data: labels.map((l) => this.byProject.get(l).duration), + data: labels.map((l) => this.byClientProject.get(l).duration), backgroundColor: labels.map((_, i) => COLORS[i % COLORS.length]), }], } }, costChartData() { - const labels = [...this.byProject.keys()] + const labels = [...this.byClientProject.keys()] return { labels, datasets: [{ - data: labels.map((l) => this.byProject.get(l).cost), + data: labels.map((l) => this.byClientProject.get(l).cost), backgroundColor: labels.map((_, i) => COLORS[i % COLORS.length]), }], } diff --git a/js/src/app/views/ReportsView.vue b/js/src/app/views/ReportsView.vue index 65021a1..52ecd25 100644 --- a/js/src/app/views/ReportsView.vue +++ b/js/src/app/views/ReportsView.vue @@ -164,11 +164,16 @@ export default { }) this.items = data.items || [] }, + ended(item) { + if (this.group1 || this.group2 || this.timegroup) return '*' + if (!item.time) return '' + return new Date((item.time + (item.totalDuration || 0)) * 1000).toLocaleString() + }, toCsv() { - const header = ['Name', 'Details', 'User', 'Project', 'Client', 'When', 'Cost', 'Total Duration'] + const header = ['Name', 'Details', 'User', 'Project', 'Client', 'When', 'Cost', 'Total Duration', 'Ended'] const rows = this.items.map((i) => [ - i.name, i.details, i.userUid, i.project, i.client, i.time, - ((i.cost || 0) / 100).toFixed(2), formatDuration(i.totalDuration), + i.name, i.details, i.userUid, i.project, i.client, this.formatWhen(i), + ((i.cost || 0) / 100).toFixed(2), formatDuration(i.totalDuration), this.ended(i), ]) return [header, ...rows].map((r) => r.map((v) => `"${String(v ?? '').replace(/"/g, '""')}"`).join(',')).join('\n') }, diff --git a/js/src/app/views/TimerView.vue b/js/src/app/views/TimerView.vue index 72c2496..315f767 100644 --- a/js/src/app/views/TimerView.vue +++ b/js/src/app/views/TimerView.vue @@ -59,15 +59,20 @@ :options="tags" label="name" multiple + taggable + push-tags placeholder="Tags" style="min-width: 160px;" @update:model-value="(t) => updateTags(item, t)" /> {{ formatDuration(item.duration) }} - + @update:model-value="(v) => (costDrafts[item.id] = v)" + @blur="commitCost(item)" /> @@ -174,6 +179,8 @@ export default { timeForm: { start: null, end: null }, manualEntryVisible: false, manualForm: { name: '', details: '', start: null, end: null }, + costDrafts: {}, + costStatus: {}, confirmVisible: false, confirmMessage: '', confirmResolver: null, @@ -304,16 +311,25 @@ export default { }, async updateTags(item, tags) { try { - await apiPost(`/update-work-interval/${item.id}`, { tagId: tags.map((t) => t.id).join(',') }) + await apiPost(`/update-work-interval/${item.id}`, { tagId: tags.map((t) => t.id ?? t.name).join(',') }) await this.loadWorkIntervals() } catch (e) { showError(e.message) } }, - async updateCost(item, value) { + costDraft(item) { + return this.costDrafts[item.id] ?? (item.cost / 100).toFixed(2) + }, + async commitCost(item) { + const value = this.costDrafts[item.id] + if (value === undefined) return try { await apiPost(`/add-cost/${item.id}`, { cost: value }) + this.costStatus[item.id] = 'success' + setTimeout(() => { this.costStatus[item.id] = null }, 3000) + await this.loadWorkIntervals() } catch (e) { + this.costStatus[item.id] = 'error' showError(e.message) } },