From 353f6b664ed89f843228484a04a74a80ea12df66 Mon Sep 17 00:00:00 2001 From: Bastean Date: Thu, 12 Sep 2024 19:03:28 +0000 Subject: [PATCH] feat(genesis): codexgo --- .air.toml | 65 + .devcontainer/devcontainer.json | 57 + .dockerignore | 59 + .gitattributes | 1 + .github/ISSUE_TEMPLATE/bug_report.md | 40 + .github/ISSUE_TEMPLATE/feature_request.md | 19 + .github/actions/setup/action.yml | 23 + .github/workflows/ci.yml | 56 + .github/workflows/release.yml | 64 + .github/workflows/upgrade.yml | 38 + .gitignore | 57 + .husky/commit-msg | 1 + .husky/pre-commit | 1 + .husky/pre-push | 1 + .prettierignore | 59 + .vscode/extensions.json | 3 + CHANGELOG.md | 550 + LICENSE | 21 + Makefile | 303 + README.md | 534 + assets/readme/desktop-dashboard.png | Bin 0 -> 46982 bytes assets/readme/desktop-home.png | Bin 0 -> 41440 bytes assets/readme/logo.png | Bin 0 -> 4820 bytes assets/readme/mail-confirm-account.png | Bin 0 -> 20860 bytes assets/readme/mobile-dashboard.png | Bin 0 -> 36906 bytes assets/readme/mobile-home.png | Bin 0 -> 33344 bytes assets/social-preview/social-preview.png | Bin 0 -> 9688 bytes cmd/codexgo/codex.go | 81 + deployments/.env.demo | 45 + deployments/.env.example | 45 + deployments/.env.example.cli | 20 + deployments/.env.example.demo | 45 + deployments/.env.example.test.acceptance | 1 + deployments/.env.example.test.integration | 1 + deployments/Dockerfile | 33 + deployments/docker-compose.yml | 86 + deployments/run.sh | 13 + go.mod | 81 + go.sum | 242 + internal/app/cli/cli.go | 46 + .../app/server/component/layout/index.templ | 71 + .../server/component/layout/index_templ.go | 96 + .../page/dashboard/form.delete.templ | 94 + .../page/dashboard/form.delete_templ.go | 132 + .../page/dashboard/form.update.templ | 160 + .../page/dashboard/form.update_templ.go | 184 + .../page/dashboard/page.dashboard.templ | 112 + .../page/dashboard/page.dashboard_templ.go | 199 + .../component/page/home/form.login.templ | 84 + .../component/page/home/form.login_templ.go | 134 + .../component/page/home/form.register.templ | 150 + .../page/home/form.register_templ.go | 199 + .../component/page/home/modal.terms.templ | 36 + .../component/page/home/modal.terms_templ.go | 54 + .../component/page/home/page.home.templ | 73 + .../component/page/home/page.home_templ.go | 176 + .../component/scripts/fomantic/fomantic.templ | 34 + .../scripts/fomantic/fomantic_templ.go | 69 + .../component/scripts/jquery/jquery.templ | 9 + .../component/scripts/jquery/jquery_templ.go | 44 + .../server/component/scripts/scripts.templ | 9 + .../server/component/scripts/scripts_templ.go | 38 + .../component/scripts/storage/storage.templ | 60 + .../scripts/storage/storage_templ.go | 95 + .../server/features/redirect/default.feature | 6 + .../app/server/features/user/create.feature | 21 + .../app/server/features/user/delete.feature | 30 + .../app/server/features/user/login.feature | 28 + .../app/server/features/user/update.feature | 30 + internal/app/server/handler/health/check.go | 11 + internal/app/server/handler/page/dashboard.go | 37 + internal/app/server/handler/page/home.go | 13 + .../app/server/handler/redirect/default.go | 11 + internal/app/server/handler/user/create.go | 34 + internal/app/server/handler/user/delete.go | 62 + internal/app/server/handler/user/login.go | 59 + internal/app/server/handler/user/update.go | 45 + internal/app/server/handler/user/verify.go | 33 + .../app/server/middleware/authentication.go | 44 + internal/app/server/middleware/cookie.go | 15 + internal/app/server/middleware/error.go | 82 + internal/app/server/middleware/header.go | 22 + internal/app/server/middleware/limiter.go | 28 + internal/app/server/middleware/recover.go | 30 + internal/app/server/package.json | 7 + internal/app/server/router/api/api.go | 41 + internal/app/server/router/router.go | 50 + internal/app/server/router/view/view.go | 37 + internal/app/server/server.go | 73 + internal/app/server/server_test.go | 159 + .../server/static/assets/apple-touch-icon.png | Bin 0 -> 1716 bytes internal/app/server/static/assets/favicon.png | Bin 0 -> 1716 bytes internal/app/server/static/assets/logo.png | Bin 0 -> 4820 bytes internal/app/server/static/assets/pwa-any.png | Bin 0 -> 4419 bytes .../app/server/static/assets/pwa-maskable.png | Bin 0 -> 4419 bytes .../components/accordion.min.css | 9 + .../components/accordion.min.js | 11 + .../fomantic-ui.com/components/ad.min.css | 10 + .../fomantic-ui.com/components/api.min.js | 11 + .../components/breadcrumb.min.css | 9 + .../fomantic-ui.com/components/button.min.css | 9 + .../components/calendar.min.css | 9 + .../components/calendar.min.js | 11 + .../fomantic-ui.com/components/card.min.css | 9 + .../components/checkbox.min.css | 9 + .../components/checkbox.min.js | 11 + .../components/comment.min.css | 9 + .../components/container.min.css | 9 + .../fomantic-ui.com/components/dimmer.min.css | 9 + .../fomantic-ui.com/components/dimmer.min.js | 11 + .../components/divider.min.css | 9 + .../components/dropdown.min.css | 9 + .../components/dropdown.min.js | 11 + .../fomantic-ui.com/components/embed.min.css | 9 + .../fomantic-ui.com/components/embed.min.js | 11 + .../fomantic-ui.com/components/emoji.min.css | 9 + .../fomantic-ui.com/components/feed.min.css | 9 + .../fomantic-ui.com/components/flag.min.css | 9 + .../fomantic-ui.com/components/flyout.min.css | 9 + .../fomantic-ui.com/components/flyout.min.js | 11 + .../fomantic-ui.com/components/form.min.css | 9 + .../fomantic-ui.com/components/form.min.js | 11 + .../fomantic-ui.com/components/grid.min.css | 9 + .../fomantic-ui.com/components/header.min.css | 9 + .../fomantic-ui.com/components/icon.min.css | 9 + .../fomantic-ui.com/components/image.min.css | 9 + .../fomantic-ui.com/components/input.min.css | 9 + .../fomantic-ui.com/components/item.min.css | 9 + .../fomantic-ui.com/components/label.min.css | 9 + .../fomantic-ui.com/components/list.min.css | 9 + .../fomantic-ui.com/components/loader.min.css | 9 + .../fomantic-ui.com/components/menu.min.css | 9 + .../components/message.min.css | 9 + .../fomantic-ui.com/components/modal.min.css | 9 + .../fomantic-ui.com/components/modal.min.js | 11 + .../fomantic-ui.com/components/nag.min.css | 9 + .../fomantic-ui.com/components/nag.min.js | 11 + .../components/placeholder.min.css | 9 + .../fomantic-ui.com/components/popup.min.css | 9 + .../fomantic-ui.com/components/popup.min.js | 11 + .../components/progress.min.css | 9 + .../components/progress.min.js | 11 + .../fomantic-ui.com/components/rail.min.css | 9 + .../fomantic-ui.com/components/rating.min.css | 9 + .../fomantic-ui.com/components/rating.min.js | 11 + .../fomantic-ui.com/components/reset.min.css | 9 + .../fomantic-ui.com/components/reveal.min.css | 9 + .../fomantic-ui.com/components/search.min.css | 9 + .../fomantic-ui.com/components/search.min.js | 11 + .../components/segment.min.css | 9 + .../fomantic-ui.com/components/shape.min.css | 9 + .../fomantic-ui.com/components/shape.min.js | 11 + .../components/sidebar.min.css | 9 + .../fomantic-ui.com/components/sidebar.min.js | 11 + .../fomantic-ui.com/components/site.min.css | 9 + .../fomantic-ui.com/components/site.min.js | 11 + .../fomantic-ui.com/components/slider.min.css | 9 + .../fomantic-ui.com/components/slider.min.js | 11 + .../fomantic-ui.com/components/state.min.js | 11 + .../components/statistic.min.css | 9 + .../fomantic-ui.com/components/step.min.css | 9 + .../fomantic-ui.com/components/sticky.min.css | 9 + .../fomantic-ui.com/components/sticky.min.js | 11 + .../fomantic-ui.com/components/tab.min.css | 9 + .../fomantic-ui.com/components/tab.min.js | 11 + .../fomantic-ui.com/components/table.min.css | 9 + .../fomantic-ui.com/components/text.min.css | 9 + .../fomantic-ui.com/components/toast.min.css | 9 + .../fomantic-ui.com/components/toast.min.js | 11 + .../components/transition.min.css | 9 + .../components/transition.min.js | 11 + .../components/visibility.min.js | 11 + .../dist/fomantic-ui.com/semantic.min.css | 11 + .../dist/fomantic-ui.com/semantic.min.js | 11 + .../default/assets/fonts/Lato-Bold.woff2 | Bin 0 -> 178868 bytes .../assets/fonts/Lato-BoldItalic.woff2 | Bin 0 -> 188332 bytes .../default/assets/fonts/Lato-Italic.woff2 | Bin 0 -> 190608 bytes .../default/assets/fonts/Lato-Regular.woff2 | Bin 0 -> 178044 bytes .../default/assets/fonts/LatoLatin-Bold.woff2 | Bin 0 -> 33616 bytes .../assets/fonts/LatoLatin-BoldItalic.woff2 | Bin 0 -> 34752 bytes .../assets/fonts/LatoLatin-Italic.woff2 | Bin 0 -> 34848 bytes .../assets/fonts/LatoLatin-Regular.woff2 | Bin 0 -> 33828 bytes .../default/assets/fonts/brand-icons.woff2 | Bin 0 -> 76736 bytes .../themes/default/assets/fonts/icons.woff2 | Bin 0 -> 78268 bytes .../default/assets/fonts/outline-icons.woff2 | Bin 0 -> 13224 bytes .../static/dist/jquery.com/jquery.min.js | 2 + .../static/dist/lodash.com/lodash.min.js | 140 + internal/app/server/static/manifest.json | 27 + internal/app/server/static/robots.txt | 2 + internal/app/server/util/errs/abort.go | 23 + internal/app/server/util/errs/binding.go | 26 + internal/app/server/util/errs/missing.go | 14 + internal/app/server/util/errs/render.go | 13 + internal/app/server/util/errs/session.go | 13 + internal/app/server/util/format/format.go | 9 + internal/app/server/util/key/key.go | 9 + internal/app/server/util/reply/reply.go | 11 + .../pkg/service/authentication/jwt/jwt.go | 16 + .../service/communication/communication.go | 58 + .../service/communication/rabbitmq/binding.go | 5 + .../communication/rabbitmq/consumers.go | 9 + .../communication/rabbitmq/exchange.go | 11 + .../service/communication/rabbitmq/queues.go | 9 + .../communication/rabbitmq/rabbitmq.go | 46 + internal/pkg/service/env/broker.go | 14 + internal/pkg/service/env/database.go | 14 + internal/pkg/service/env/env.go | 114 + internal/pkg/service/env/jwt.go | 13 + internal/pkg/service/env/server.go | 29 + internal/pkg/service/env/smtp.go | 20 + internal/pkg/service/errors/errors.go | 37 + internal/pkg/service/logger/log/log.go | 112 + internal/pkg/service/module/module.go | 40 + internal/pkg/service/module/user/consumer.go | 20 + internal/pkg/service/module/user/handler.go | 35 + internal/pkg/service/module/user/hashing.go | 9 + internal/pkg/service/module/user/message.go | 17 + .../pkg/service/module/user/repository.go | 13 + internal/pkg/service/module/user/transfer.go | 11 + internal/pkg/service/module/user/user.go | 55 + .../service/persistence/mongodb/mongodb.go | 14 + .../pkg/service/persistence/persistence.go | 52 + internal/pkg/service/service.go | 52 + internal/pkg/service/transport/smtp/smtp.go | 14 + internal/pkg/service/transport/transport.go | 53 + package-lock.json | 14276 ++++++++++++++++ package.json | 138 + pkg/context/shared/domain/aggregates/root.go | 27 + pkg/context/shared/domain/errors/bubble.go | 52 + pkg/context/shared/domain/errors/bubbleup.go | 9 + pkg/context/shared/domain/errors/default.go | 5 + pkg/context/shared/domain/errors/exist.go | 31 + pkg/context/shared/domain/errors/failure.go | 16 + pkg/context/shared/domain/errors/internal.go | 16 + pkg/context/shared/domain/errors/invalid.go | 16 + pkg/context/shared/domain/errors/meta.go | 5 + pkg/context/shared/domain/errors/panic.go | 9 + pkg/context/shared/domain/errors/wrap.go | 17 + pkg/context/shared/domain/handlers/command.go | 5 + pkg/context/shared/domain/handlers/query.go | 5 + pkg/context/shared/domain/loggers/logger.go | 9 + pkg/context/shared/domain/messages/broker.go | 9 + .../shared/domain/messages/consumer.go | 6 + pkg/context/shared/domain/messages/key.go | 76 + .../shared/domain/messages/key_test.go | 41 + pkg/context/shared/domain/messages/message.go | 19 + pkg/context/shared/domain/messages/queue.go | 23 + .../shared/domain/messages/recipient.go | 53 + .../shared/domain/messages/recipient_test.go | 39 + pkg/context/shared/domain/messages/router.go | 5 + .../domain/messages/valueobjs/action.go | 38 + .../messages/valueobjs/action.mother.go | 24 + .../domain/messages/valueobjs/action_test.go | 38 + .../domain/messages/valueobjs/command.go | 38 + .../messages/valueobjs/command.mother.go | 32 + .../domain/messages/valueobjs/command_test.go | 57 + .../domain/messages/valueobjs/entity.go | 38 + .../messages/valueobjs/entity.mother.go | 32 + .../domain/messages/valueobjs/entity_test.go | 57 + .../shared/domain/messages/valueobjs/event.go | 38 + .../domain/messages/valueobjs/event.mother.go | 32 + .../domain/messages/valueobjs/event_test.go | 57 + .../domain/messages/valueobjs/organization.go | 38 + .../messages/valueobjs/organization.mother.go | 32 + .../messages/valueobjs/organization_test.go | 57 + .../domain/messages/valueobjs/service.go | 38 + .../messages/valueobjs/service.mother.go | 32 + .../domain/messages/valueobjs/service_test.go | 57 + .../domain/messages/valueobjs/status.go | 38 + .../messages/valueobjs/status.mother.go | 24 + .../domain/messages/valueobjs/status_test.go | 38 + .../shared/domain/messages/valueobjs/type.go | 38 + .../domain/messages/valueobjs/type.mother.go | 24 + .../domain/messages/valueobjs/type_test.go | 38 + .../domain/messages/valueobjs/version.go | 32 + .../messages/valueobjs/version.mother.go | 24 + .../domain/messages/valueobjs/version_test.go | 38 + pkg/context/shared/domain/services/context.go | 21 + pkg/context/shared/domain/services/mother.go | 23 + .../shared/domain/services/validate.go | 13 + .../shared/domain/transfers/transfer.go | 5 + .../infrastructure/authentications/jwt/jwt.go | 54 + .../communications/broker.mock.go | 35 + .../communications/consumer.mock.go | 20 + .../communications/rabbitmq/rabbitmq.go | 290 + .../communications/rabbitmq/rabbitmq_test.go | 104 + .../persistences/mongodb/mongodb.go | 90 + .../shared/infrastructure/records/log/log.go | 40 + .../infrastructure/records/logger.mock.go | 29 + .../infrastructure/transports/smtp/smtp.go | 53 + .../transports/transfer.mock.go | 14 + .../user/application/create/command.go | 5 + .../application/create/command.handler.go | 36 + .../create/command.handler_test.go | 65 + .../user/application/create/command.mother.go | 19 + pkg/context/user/application/create/create.go | 21 + .../application/created/created.consumer.go | 48 + .../created/created.consumer_test.go | 66 + .../user/application/created/created.go | 21 + .../user/application/delete/command.go | 5 + .../application/delete/command.handler.go | 30 + .../delete/command.handler_test.go | 64 + .../user/application/delete/command.mother.go | 15 + pkg/context/user/application/delete/delete.go | 38 + pkg/context/user/application/login/login.go | 32 + pkg/context/user/application/login/query.go | 5 + .../user/application/login/query.handler.go | 32 + .../application/login/query.handler_test.go | 70 + .../user/application/login/query.mother.go | 15 + .../user/application/login/response.go | 6 + pkg/context/user/application/read/query.go | 5 + .../user/application/read/query.handler.go | 29 + .../application/read/query.handler_test.go | 60 + .../user/application/read/query.mother.go | 13 + pkg/context/user/application/read/read.go | 23 + pkg/context/user/application/read/response.go | 6 + .../user/application/update/command.go | 5 + .../application/update/command.handler.go | 42 + .../update/command.handler_test.go | 74 + .../user/application/update/command.mother.go | 21 + pkg/context/user/application/update/update.go | 44 + .../user/application/verify/command.go | 5 + .../application/verify/command.handler.go | 27 + .../verify/command.handler_test.go | 60 + .../user/application/verify/command.mother.go | 13 + pkg/context/user/application/verify/verify.go | 33 + .../user/domain/aggregate/user/created.go | 42 + .../domain/aggregate/user/created.mother.go | 26 + .../user/domain/aggregate/user/email.go | 32 + .../domain/aggregate/user/email.mother.go | 24 + .../user/domain/aggregate/user/email_test.go | 38 + pkg/context/user/domain/aggregate/user/id.go | 32 + .../user/domain/aggregate/user/id.mother.go | 24 + .../user/domain/aggregate/user/id_test.go | 38 + .../user/domain/aggregate/user/password.go | 35 + .../domain/aggregate/user/password.mother.go | 24 + .../domain/aggregate/user/password_test.go | 38 + .../user/domain/aggregate/user/user.mother.go | 29 + .../user/domain/aggregate/user/user.root.go | 89 + .../user/domain/aggregate/user/username.go | 38 + .../domain/aggregate/user/username.mother.go | 32 + .../domain/aggregate/user/username_test.go | 57 + .../user/domain/aggregate/user/verified.go | 30 + pkg/context/user/domain/hashing/hashing.go | 6 + .../user/domain/repository/repository.go | 18 + pkg/context/user/domain/service/password.go | 17 + pkg/context/user/domain/usecase/usecase.go | 32 + .../cryptographic/bcrypt/bcrypt.go | 27 + .../cryptographic/bcrypt/bcrypt_test.go | 49 + .../cryptographic/hashing.mock.go | 19 + .../persistence/collection/user.go | 207 + .../persistence/collection/user_test.go | 208 + .../infrastructure/persistence/user.mock.go | 36 + .../transport/mail/confirmation.go | 69 + .../transport/mail/confirmation.templ | 48 + .../transport/mail/confirmation_templ.go | 59 + .../transport/mail/confirmation_test.go | 51 + .../transport/terminal/confirmation.go | 35 + .../transport/terminal/confirmation_test.go | 54 + scripts/copydeps/copydeps.go | 113 + scripts/syncenv/syncenv.go | 221 + scripts/upgrade/upgrade.go | 51 + test/.gitkeep | 0 363 files changed, 27686 insertions(+) create mode 100644 .air.toml create mode 100644 .devcontainer/devcontainer.json create mode 100644 .dockerignore create mode 100644 .gitattributes create mode 100644 .github/ISSUE_TEMPLATE/bug_report.md create mode 100644 .github/ISSUE_TEMPLATE/feature_request.md create mode 100644 .github/actions/setup/action.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/release.yml create mode 100644 .github/workflows/upgrade.yml create mode 100644 .gitignore create mode 100755 .husky/commit-msg create mode 100755 .husky/pre-commit create mode 100755 .husky/pre-push create mode 100644 .prettierignore create mode 100644 .vscode/extensions.json create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 assets/readme/desktop-dashboard.png create mode 100644 assets/readme/desktop-home.png create mode 100644 assets/readme/logo.png create mode 100644 assets/readme/mail-confirm-account.png create mode 100644 assets/readme/mobile-dashboard.png create mode 100644 assets/readme/mobile-home.png create mode 100644 assets/social-preview/social-preview.png create mode 100644 cmd/codexgo/codex.go create mode 100644 deployments/.env.demo create mode 100644 deployments/.env.example create mode 100644 deployments/.env.example.cli create mode 100644 deployments/.env.example.demo create mode 100644 deployments/.env.example.test.acceptance create mode 100644 deployments/.env.example.test.integration create mode 100644 deployments/Dockerfile create mode 100644 deployments/docker-compose.yml create mode 100644 deployments/run.sh create mode 100644 go.mod create mode 100644 go.sum create mode 100644 internal/app/cli/cli.go create mode 100644 internal/app/server/component/layout/index.templ create mode 100644 internal/app/server/component/layout/index_templ.go create mode 100644 internal/app/server/component/page/dashboard/form.delete.templ create mode 100644 internal/app/server/component/page/dashboard/form.delete_templ.go create mode 100644 internal/app/server/component/page/dashboard/form.update.templ create mode 100644 internal/app/server/component/page/dashboard/form.update_templ.go create mode 100644 internal/app/server/component/page/dashboard/page.dashboard.templ create mode 100644 internal/app/server/component/page/dashboard/page.dashboard_templ.go create mode 100644 internal/app/server/component/page/home/form.login.templ create mode 100644 internal/app/server/component/page/home/form.login_templ.go create mode 100644 internal/app/server/component/page/home/form.register.templ create mode 100644 internal/app/server/component/page/home/form.register_templ.go create mode 100644 internal/app/server/component/page/home/modal.terms.templ create mode 100644 internal/app/server/component/page/home/modal.terms_templ.go create mode 100644 internal/app/server/component/page/home/page.home.templ create mode 100644 internal/app/server/component/page/home/page.home_templ.go create mode 100644 internal/app/server/component/scripts/fomantic/fomantic.templ create mode 100644 internal/app/server/component/scripts/fomantic/fomantic_templ.go create mode 100644 internal/app/server/component/scripts/jquery/jquery.templ create mode 100644 internal/app/server/component/scripts/jquery/jquery_templ.go create mode 100644 internal/app/server/component/scripts/scripts.templ create mode 100644 internal/app/server/component/scripts/scripts_templ.go create mode 100644 internal/app/server/component/scripts/storage/storage.templ create mode 100644 internal/app/server/component/scripts/storage/storage_templ.go create mode 100644 internal/app/server/features/redirect/default.feature create mode 100644 internal/app/server/features/user/create.feature create mode 100644 internal/app/server/features/user/delete.feature create mode 100644 internal/app/server/features/user/login.feature create mode 100644 internal/app/server/features/user/update.feature create mode 100644 internal/app/server/handler/health/check.go create mode 100644 internal/app/server/handler/page/dashboard.go create mode 100644 internal/app/server/handler/page/home.go create mode 100644 internal/app/server/handler/redirect/default.go create mode 100644 internal/app/server/handler/user/create.go create mode 100644 internal/app/server/handler/user/delete.go create mode 100644 internal/app/server/handler/user/login.go create mode 100644 internal/app/server/handler/user/update.go create mode 100644 internal/app/server/handler/user/verify.go create mode 100644 internal/app/server/middleware/authentication.go create mode 100644 internal/app/server/middleware/cookie.go create mode 100644 internal/app/server/middleware/error.go create mode 100644 internal/app/server/middleware/header.go create mode 100644 internal/app/server/middleware/limiter.go create mode 100644 internal/app/server/middleware/recover.go create mode 100644 internal/app/server/package.json create mode 100644 internal/app/server/router/api/api.go create mode 100644 internal/app/server/router/router.go create mode 100644 internal/app/server/router/view/view.go create mode 100644 internal/app/server/server.go create mode 100644 internal/app/server/server_test.go create mode 100644 internal/app/server/static/assets/apple-touch-icon.png create mode 100644 internal/app/server/static/assets/favicon.png create mode 100644 internal/app/server/static/assets/logo.png create mode 100644 internal/app/server/static/assets/pwa-any.png create mode 100644 internal/app/server/static/assets/pwa-maskable.png create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/accordion.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/accordion.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/ad.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/api.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/breadcrumb.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/button.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/card.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/comment.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/container.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/divider.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/embed.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/embed.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/emoji.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/feed.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/flag.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/flyout.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/flyout.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/form.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/form.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/grid.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/header.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/icon.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/image.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/input.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/item.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/label.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/list.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/loader.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/menu.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/message.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/modal.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/modal.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/nag.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/nag.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/placeholder.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/popup.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/popup.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/progress.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/progress.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/rail.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/rating.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/rating.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/reset.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/reveal.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/search.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/search.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/segment.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/shape.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/shape.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/sidebar.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/sidebar.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/site.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/site.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/slider.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/slider.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/state.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/statistic.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/step.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/sticky.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/sticky.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/tab.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/tab.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/table.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/text.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/toast.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/toast.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/transition.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/transition.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/components/visibility.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/semantic.min.css create mode 100755 internal/app/server/static/dist/fomantic-ui.com/semantic.min.js create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/Lato-Bold.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/Lato-BoldItalic.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/Lato-Italic.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/Lato-Regular.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/LatoLatin-Bold.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/LatoLatin-BoldItalic.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/LatoLatin-Italic.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/LatoLatin-Regular.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/brand-icons.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/icons.woff2 create mode 100755 internal/app/server/static/dist/fomantic-ui.com/themes/default/assets/fonts/outline-icons.woff2 create mode 100755 internal/app/server/static/dist/jquery.com/jquery.min.js create mode 100755 internal/app/server/static/dist/lodash.com/lodash.min.js create mode 100644 internal/app/server/static/manifest.json create mode 100644 internal/app/server/static/robots.txt create mode 100644 internal/app/server/util/errs/abort.go create mode 100644 internal/app/server/util/errs/binding.go create mode 100644 internal/app/server/util/errs/missing.go create mode 100644 internal/app/server/util/errs/render.go create mode 100644 internal/app/server/util/errs/session.go create mode 100644 internal/app/server/util/format/format.go create mode 100644 internal/app/server/util/key/key.go create mode 100644 internal/app/server/util/reply/reply.go create mode 100644 internal/pkg/service/authentication/jwt/jwt.go create mode 100644 internal/pkg/service/communication/communication.go create mode 100644 internal/pkg/service/communication/rabbitmq/binding.go create mode 100644 internal/pkg/service/communication/rabbitmq/consumers.go create mode 100644 internal/pkg/service/communication/rabbitmq/exchange.go create mode 100644 internal/pkg/service/communication/rabbitmq/queues.go create mode 100644 internal/pkg/service/communication/rabbitmq/rabbitmq.go create mode 100644 internal/pkg/service/env/broker.go create mode 100644 internal/pkg/service/env/database.go create mode 100644 internal/pkg/service/env/env.go create mode 100644 internal/pkg/service/env/jwt.go create mode 100644 internal/pkg/service/env/server.go create mode 100644 internal/pkg/service/env/smtp.go create mode 100644 internal/pkg/service/errors/errors.go create mode 100644 internal/pkg/service/logger/log/log.go create mode 100644 internal/pkg/service/module/module.go create mode 100644 internal/pkg/service/module/user/consumer.go create mode 100644 internal/pkg/service/module/user/handler.go create mode 100644 internal/pkg/service/module/user/hashing.go create mode 100644 internal/pkg/service/module/user/message.go create mode 100644 internal/pkg/service/module/user/repository.go create mode 100644 internal/pkg/service/module/user/transfer.go create mode 100644 internal/pkg/service/module/user/user.go create mode 100644 internal/pkg/service/persistence/mongodb/mongodb.go create mode 100644 internal/pkg/service/persistence/persistence.go create mode 100644 internal/pkg/service/service.go create mode 100644 internal/pkg/service/transport/smtp/smtp.go create mode 100644 internal/pkg/service/transport/transport.go create mode 100644 package-lock.json create mode 100644 package.json create mode 100644 pkg/context/shared/domain/aggregates/root.go create mode 100644 pkg/context/shared/domain/errors/bubble.go create mode 100644 pkg/context/shared/domain/errors/bubbleup.go create mode 100644 pkg/context/shared/domain/errors/default.go create mode 100644 pkg/context/shared/domain/errors/exist.go create mode 100644 pkg/context/shared/domain/errors/failure.go create mode 100644 pkg/context/shared/domain/errors/internal.go create mode 100644 pkg/context/shared/domain/errors/invalid.go create mode 100644 pkg/context/shared/domain/errors/meta.go create mode 100644 pkg/context/shared/domain/errors/panic.go create mode 100644 pkg/context/shared/domain/errors/wrap.go create mode 100644 pkg/context/shared/domain/handlers/command.go create mode 100644 pkg/context/shared/domain/handlers/query.go create mode 100644 pkg/context/shared/domain/loggers/logger.go create mode 100644 pkg/context/shared/domain/messages/broker.go create mode 100644 pkg/context/shared/domain/messages/consumer.go create mode 100644 pkg/context/shared/domain/messages/key.go create mode 100644 pkg/context/shared/domain/messages/key_test.go create mode 100644 pkg/context/shared/domain/messages/message.go create mode 100644 pkg/context/shared/domain/messages/queue.go create mode 100644 pkg/context/shared/domain/messages/recipient.go create mode 100644 pkg/context/shared/domain/messages/recipient_test.go create mode 100644 pkg/context/shared/domain/messages/router.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/action.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/action.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/action_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/command.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/command.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/command_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/entity.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/entity.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/entity_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/event.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/event.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/event_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/organization.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/organization.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/organization_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/service.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/service.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/service_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/status.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/status.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/status_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/type.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/type.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/type_test.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/version.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/version.mother.go create mode 100644 pkg/context/shared/domain/messages/valueobjs/version_test.go create mode 100644 pkg/context/shared/domain/services/context.go create mode 100644 pkg/context/shared/domain/services/mother.go create mode 100644 pkg/context/shared/domain/services/validate.go create mode 100644 pkg/context/shared/domain/transfers/transfer.go create mode 100644 pkg/context/shared/infrastructure/authentications/jwt/jwt.go create mode 100644 pkg/context/shared/infrastructure/communications/broker.mock.go create mode 100644 pkg/context/shared/infrastructure/communications/consumer.mock.go create mode 100644 pkg/context/shared/infrastructure/communications/rabbitmq/rabbitmq.go create mode 100644 pkg/context/shared/infrastructure/communications/rabbitmq/rabbitmq_test.go create mode 100644 pkg/context/shared/infrastructure/persistences/mongodb/mongodb.go create mode 100644 pkg/context/shared/infrastructure/records/log/log.go create mode 100644 pkg/context/shared/infrastructure/records/logger.mock.go create mode 100644 pkg/context/shared/infrastructure/transports/smtp/smtp.go create mode 100644 pkg/context/shared/infrastructure/transports/transfer.mock.go create mode 100644 pkg/context/user/application/create/command.go create mode 100644 pkg/context/user/application/create/command.handler.go create mode 100644 pkg/context/user/application/create/command.handler_test.go create mode 100644 pkg/context/user/application/create/command.mother.go create mode 100644 pkg/context/user/application/create/create.go create mode 100644 pkg/context/user/application/created/created.consumer.go create mode 100644 pkg/context/user/application/created/created.consumer_test.go create mode 100644 pkg/context/user/application/created/created.go create mode 100644 pkg/context/user/application/delete/command.go create mode 100644 pkg/context/user/application/delete/command.handler.go create mode 100644 pkg/context/user/application/delete/command.handler_test.go create mode 100644 pkg/context/user/application/delete/command.mother.go create mode 100644 pkg/context/user/application/delete/delete.go create mode 100644 pkg/context/user/application/login/login.go create mode 100644 pkg/context/user/application/login/query.go create mode 100644 pkg/context/user/application/login/query.handler.go create mode 100644 pkg/context/user/application/login/query.handler_test.go create mode 100644 pkg/context/user/application/login/query.mother.go create mode 100644 pkg/context/user/application/login/response.go create mode 100644 pkg/context/user/application/read/query.go create mode 100644 pkg/context/user/application/read/query.handler.go create mode 100644 pkg/context/user/application/read/query.handler_test.go create mode 100644 pkg/context/user/application/read/query.mother.go create mode 100644 pkg/context/user/application/read/read.go create mode 100644 pkg/context/user/application/read/response.go create mode 100644 pkg/context/user/application/update/command.go create mode 100644 pkg/context/user/application/update/command.handler.go create mode 100644 pkg/context/user/application/update/command.handler_test.go create mode 100644 pkg/context/user/application/update/command.mother.go create mode 100644 pkg/context/user/application/update/update.go create mode 100644 pkg/context/user/application/verify/command.go create mode 100644 pkg/context/user/application/verify/command.handler.go create mode 100644 pkg/context/user/application/verify/command.handler_test.go create mode 100644 pkg/context/user/application/verify/command.mother.go create mode 100644 pkg/context/user/application/verify/verify.go create mode 100644 pkg/context/user/domain/aggregate/user/created.go create mode 100644 pkg/context/user/domain/aggregate/user/created.mother.go create mode 100644 pkg/context/user/domain/aggregate/user/email.go create mode 100644 pkg/context/user/domain/aggregate/user/email.mother.go create mode 100644 pkg/context/user/domain/aggregate/user/email_test.go create mode 100644 pkg/context/user/domain/aggregate/user/id.go create mode 100644 pkg/context/user/domain/aggregate/user/id.mother.go create mode 100644 pkg/context/user/domain/aggregate/user/id_test.go create mode 100644 pkg/context/user/domain/aggregate/user/password.go create mode 100644 pkg/context/user/domain/aggregate/user/password.mother.go create mode 100644 pkg/context/user/domain/aggregate/user/password_test.go create mode 100644 pkg/context/user/domain/aggregate/user/user.mother.go create mode 100644 pkg/context/user/domain/aggregate/user/user.root.go create mode 100644 pkg/context/user/domain/aggregate/user/username.go create mode 100644 pkg/context/user/domain/aggregate/user/username.mother.go create mode 100644 pkg/context/user/domain/aggregate/user/username_test.go create mode 100644 pkg/context/user/domain/aggregate/user/verified.go create mode 100644 pkg/context/user/domain/hashing/hashing.go create mode 100644 pkg/context/user/domain/repository/repository.go create mode 100644 pkg/context/user/domain/service/password.go create mode 100644 pkg/context/user/domain/usecase/usecase.go create mode 100644 pkg/context/user/infrastructure/cryptographic/bcrypt/bcrypt.go create mode 100644 pkg/context/user/infrastructure/cryptographic/bcrypt/bcrypt_test.go create mode 100644 pkg/context/user/infrastructure/cryptographic/hashing.mock.go create mode 100644 pkg/context/user/infrastructure/persistence/collection/user.go create mode 100644 pkg/context/user/infrastructure/persistence/collection/user_test.go create mode 100644 pkg/context/user/infrastructure/persistence/user.mock.go create mode 100644 pkg/context/user/infrastructure/transport/mail/confirmation.go create mode 100644 pkg/context/user/infrastructure/transport/mail/confirmation.templ create mode 100644 pkg/context/user/infrastructure/transport/mail/confirmation_templ.go create mode 100644 pkg/context/user/infrastructure/transport/mail/confirmation_test.go create mode 100644 pkg/context/user/infrastructure/transport/terminal/confirmation.go create mode 100644 pkg/context/user/infrastructure/transport/terminal/confirmation_test.go create mode 100644 scripts/copydeps/copydeps.go create mode 100644 scripts/syncenv/syncenv.go create mode 100644 scripts/upgrade/upgrade.go create mode 100644 test/.gitkeep diff --git a/.air.toml b/.air.toml new file mode 100644 index 0000000..c9e8f37 --- /dev/null +++ b/.air.toml @@ -0,0 +1,65 @@ +root = "." +tmp_dir = "tmp" +testdata_dir = "testdata" + +[build] + pre_cmd = ["make generate-required"] + cmd = "go build -buildvcs=false -o ./tmp/main ./cmd/codexgo" + post_cmd = [] + bin = "./tmp/main" + full_bin = "" + args_bin = [] + include_ext = [ + "go", + "html", + "templ", + "tmpl", + "tpl" + ] + exclude_dir = [] + include_dir = [ + "cmd", + "internal", + "pkg" + ] + include_file = [] + exclude_file = [] + exclude_regex = [ + "^.*_test\\.go$", + "^.*\\.mother\\.go$", + "^.*\\.mock\\.go$", + "^.*_templ\\.go$" + ] + exclude_unchanged = true + follow_symlink = true + log = "air.log" + poll = false + poll_interval = 1000 + delay = 1000 + stop_on_error = false + send_interrupt = true + kill_delay = 1000 + rerun = false + rerun_delay = 1000 + +[log] + time = true + main_only = false + +[color] + main = "magenta" + watcher = "cyan" + build = "yellow" + runner = "green" + +[misc] + clean_on_exit = true + +[screen] + clear_on_rebuild = true + keep_scroll = true + +[proxy] + enabled = true + proxy_port = 8090 + app_port = 8080 diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..a71235f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,57 @@ +{ + "name": "codexgo", + "image": "mcr.microsoft.com/devcontainers/base:bookworm", + "features": { + "ghcr.io/devcontainers/features/sshd:1": {}, + "ghcr.io/devcontainers/features/docker-in-docker:2": {}, + "ghcr.io/devcontainers/features/node:1": {}, + "ghcr.io/devcontainers/features/go:1": { + "version": "1.23" + } + }, + "forwardPorts": [2222], + "postCreateCommand": "USER_PASSWORD=vscode make devcontainer && make init", + "customizations": { + "vscode": { + "extensions": [ + "a-h.templ", + "aaron-bond.better-comments", + "CucumberOpen.cucumber-official", + "esbenp.prettier-vscode", + "github.vscode-github-actions", + "golang.go", + "Gruntfuggly.todo-tree", + "ms-azuretools.vscode-docker", + "ms-vscode.makefile-tools", + "redhat.vscode-yaml", + "streetsidesoftware.code-spell-checker", + "tamasfe.even-better-toml", + "thejltres.fomantic-ui-snippets" + ], + "settings": { + "[cucumber]": { + "editor.defaultFormatter": "CucumberOpen.cucumber-official" + }, + "[go]": { + "editor.defaultFormatter": "golang.go" + }, + "[templ]": { + "editor.defaultFormatter": "a-h.templ" + }, + "cSpell.language": "en,lorem", + "cucumber.features": ["**/internal/app/**/*.feature"], + "cucumber.glue": ["**/internal/app/**/*_test.go"], + "editor.defaultFormatter": "esbenp.prettier-vscode", + "editor.formatOnPaste": true, + "editor.formatOnSave": true, + "emmet.includeLanguages": { + "templ": "html" + }, + "go.toolsManagement.autoUpdate": true, + "gopls": { + "ui.semanticTokens": true + } + } + } + } +} diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..03303b8 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,59 @@ +#* Editor Directories & Files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +*.local + +#* Package Managers +vendor +node_modules +package +pnpm-lock.yaml +yarn.lock +go.work.sum + +#* Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +#* ENV +*.env* +!*.env.demo* +!*.env.example* +*.npmrc* + +#* Database +*.db* +!*.db.demo* +!*.db.example* + +#* Production +dist +dist-ssr +build + +#* Tooling +vite.config.js.timestamp-* +vite.config.ts.timestamp-* +*_templ.txt +*_templ.go + +#* Misc +ignore* +report* +temp* +tmp* + +#* Repository diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..6313b56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 0000000..9b77ea7 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,40 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "" +labels: "" +assignees: "" +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**To Reproduce** +Steps to reproduce the behavior: + +1. Go to '...' +2. Click on '....' +3. Scroll down to '....' +4. See error + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Desktop (please complete the following information):** + +- OS: [e.g. iOS] +- Browser [e.g. chrome, safari] +- Version [e.g. 22] + +**Smartphone (please complete the following information):** + +- Device: [e.g. iPhone6] +- OS: [e.g. iOS8.1] +- Browser [e.g. stock browser, safari] +- Version [e.g. 22] + +**Additional context** +Add any other context about the problem here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 0000000..2bc5d5f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,19 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "" +labels: "" +assignees: "" +--- + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] + +**Describe the solution you'd like** +A clear and concise description of what you want to happen. + +**Describe alternatives you've considered** +A clear and concise description of any alternative solutions or features you've considered. + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/actions/setup/action.yml b/.github/actions/setup/action.yml new file mode 100644 index 0000000..855be7e --- /dev/null +++ b/.github/actions/setup/action.yml @@ -0,0 +1,23 @@ +name: Setup + +description: Setup & Caching Dependencies + +runs: + using: "composite" + + steps: + - name: Setup Go + uses: actions/setup-go@v5 + with: + go-version-file: "go.mod" + cache-dependency-path: "go.sum" + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version-file: "package.json" + cache: "npm" + + - name: Setup codexGO + shell: ${{ runner.os == 'Windows' && 'pwsh' || 'bash' }} + run: make init-ci diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..64f9d8f --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,56 @@ +name: CI + +on: + push: + branches: [main, ci/**] + pull_request: + branches: [main] + +jobs: + TruffleHog: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Secret Scanning + uses: trufflesecurity/trufflehog@main + with: + extra_args: --only-verified + + Lint: + runs-on: ubuntu-latest + timeout-minutes: 5 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Check + run: make lint-check + + Test: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup + uses: ./.github/actions/setup + + - name: Unit + run: make test-unit + + - name: Upload Report + uses: actions/upload-artifact@v4 + if: success() || failure() + with: + name: Test Report + path: ./test/report + retention-days: 30 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..c5bddab --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,64 @@ +name: Release + +on: + workflow_dispatch: + inputs: + status: + type: choice + description: Status + options: + - alpha + - beta + - stable + default: stable + + bump: + type: choice + description: Bump + options: + - patch + - minor + - major + - auto + default: auto + + dry: + type: boolean + description: Dry Release + default: false + +jobs: + Generate: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup + uses: ./.github/actions/setup + + - name: Import GPG Key + id: import-gpg + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ secrets.BOT_GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.BOT_GPG_PASSPHRASE }} + git_config_global: true + git_user_signingkey: true + git_commit_gpgsign: true + git_tag_gpgsign: true + + - name: Generate Release + run: OPTIONS="$STATUS_ARG $BUMP_ARG $DRY_ARG" make release-ci + env: + STATUS_ARG: ${{ fromJSON('{"alpha":"--preRelease=alpha", "beta":"--preRelease=beta", "stable":""}')[github.event.inputs.status] }} + BUMP_ARG: ${{ fromJSON('{"patch":"-i patch", "minor":"-i minor", "major":"-i major", "auto":""}')[github.event.inputs.bump] }} + DRY_ARG: ${{ github.event.inputs.dry == 'true' && '-d' || '' }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GIT_AUTHOR_NAME: ${{ steps.import-gpg.outputs.name }} + GIT_AUTHOR_EMAIL: ${{ steps.import-gpg.outputs.email }} + GIT_COMMITTER_NAME: ${{ steps.import-gpg.outputs.name }} + GIT_COMMITTER_EMAIL: ${{ steps.import-gpg.outputs.email }} diff --git a/.github/workflows/upgrade.yml b/.github/workflows/upgrade.yml new file mode 100644 index 0000000..97e2934 --- /dev/null +++ b/.github/workflows/upgrade.yml @@ -0,0 +1,38 @@ +name: Upgrade + +on: + workflow_dispatch: + +jobs: + Dependencies: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - name: Checkout + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup + uses: ./.github/actions/setup + + - name: Import GPG Key + id: import-gpg + uses: crazy-max/ghaction-import-gpg@v6 + with: + gpg_private_key: ${{ secrets.BOT_GPG_PRIVATE_KEY }} + passphrase: ${{ secrets.BOT_GPG_PASSPHRASE }} + git_config_global: true + git_user_signingkey: true + git_commit_gpgsign: true + git_tag_gpgsign: true + + - name: Upgrade Dependencies + run: | + make upgrade + git push origin main + env: + GIT_AUTHOR_NAME: ${{ steps.import-gpg.outputs.name }} + GIT_AUTHOR_EMAIL: ${{ steps.import-gpg.outputs.email }} + GIT_COMMITTER_NAME: ${{ steps.import-gpg.outputs.name }} + GIT_COMMITTER_EMAIL: ${{ steps.import-gpg.outputs.email }} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..7d9ffbb --- /dev/null +++ b/.gitignore @@ -0,0 +1,57 @@ +#* Editor Directories & Files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +*.local + +#* Package Managers +vendor +node_modules +package +pnpm-lock.yaml +yarn.lock +go.work.sum + +#* Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +#* ENV +*.env* +!*.env.demo* +!*.env.example* +*.npmrc* + +#* Database +*.db* +!*.db.demo* +!*.db.example* + +#* Production +dist-ssr +build + +#* Tooling +vite.config.js.timestamp-* +vite.config.ts.timestamp-* +*_templ.txt + +#* Misc +ignore* +report* +temp* +tmp* + +#* Repository diff --git a/.husky/commit-msg b/.husky/commit-msg new file mode 100755 index 0000000..0398b7a --- /dev/null +++ b/.husky/commit-msg @@ -0,0 +1 @@ +npx --no -- commitlint --edit ${1} diff --git a/.husky/pre-commit b/.husky/pre-commit new file mode 100755 index 0000000..1524ad6 --- /dev/null +++ b/.husky/pre-commit @@ -0,0 +1 @@ +npx --no -- lint-staged diff --git a/.husky/pre-push b/.husky/pre-push new file mode 100755 index 0000000..41b8dd7 --- /dev/null +++ b/.husky/pre-push @@ -0,0 +1 @@ +make scan-leaks-local diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..03303b8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,59 @@ +#* Editor Directories & Files +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +*.local + +#* Package Managers +vendor +node_modules +package +pnpm-lock.yaml +yarn.lock +go.work.sum + +#* Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +#* ENV +*.env* +!*.env.demo* +!*.env.example* +*.npmrc* + +#* Database +*.db* +!*.db.demo* +!*.db.example* + +#* Production +dist +dist-ssr +build + +#* Tooling +vite.config.js.timestamp-* +vite.config.ts.timestamp-* +*_templ.txt +*_templ.go + +#* Misc +ignore* +report* +temp* +tmp* + +#* Repository diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..082bc94 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["ms-vscode-remote.remote-containers"] +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..430b1e1 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,550 @@ +# Changelog + +## [4.7.1](https://github.com/bastean/codexgo/compare/v4.7.0...v4.7.1) (2024-09-07) + +### Documentation + +- **readme:** change module version in cli installation ([b598963](https://github.com/bastean/codexgo/commit/b598963671980887578531b3ecafa85aae49235f)) + +## [4.7.0](https://github.com/bastean/codexgo/compare/v4.6.3...v4.7.0) (2024-09-07) + +### Chores + +- **deps:** upgrade ([40d014f](https://github.com/bastean/codexgo/commit/40d014fbcb24b9e4944294c628554959e1bfa4a3)) +- **deps:** upgrade ([2cdc473](https://github.com/bastean/codexgo/commit/2cdc47398b43d21a15e25ebc7787cf5a66b6e15d)) + +### Documentation + +- **readme:** add cli app description ([d1722a4](https://github.com/bastean/codexgo/commit/d1722a439061a0ad4a0248da43aa65b1d14a30d8)) + +### New Features + +- **presentation:** add cli app ([eec5814](https://github.com/bastean/codexgo/commit/eec5814bdf547b79269f470c9465378f8e067d4f)) +- **presentation:** add env verification ([2198845](https://github.com/bastean/codexgo/commit/219884556422356b02c7fba2fd28356a397f3ae5)) +- **presentation:** add files needed to use the standalone binary ([eafe041](https://github.com/bastean/codexgo/commit/eafe041e95a8f23fb1b71660a30bc3104f415469)) + +### Bug Fixes + +- **makefile:** add compose exit code in prod and demo rules ([4d46bf4](https://github.com/bastean/codexgo/commit/4d46bf4caf18bd20eb1d61b2d19aabbb2f594f2d)) + +### Refactors + +- **application:** rename use case receivers ([d0bd981](https://github.com/bastean/codexgo/commit/d0bd981c3390e20165be3ad2960030f9abd313dc)) +- **env:** add codexgo prefix ([b5f6f69](https://github.com/bastean/codexgo/commit/b5f6f6960c477be80731b17bda6ab6ff3577a646)) +- **presentation:** change services initialization ([6ef228b](https://github.com/bastean/codexgo/commit/6ef228b8a781afed2f8d643bc084431f17bfc304)) +- **presentation:** change type assertions ([b1d4e18](https://github.com/bastean/codexgo/commit/b1d4e18beefa5fa44289998b36bc93c34c34f671)) +- **presentation:** wrap third-party errors on the server ([03ea027](https://github.com/bastean/codexgo/commit/03ea027f4a9d2e426bada674f26438e8b896c78e)) + +## [4.6.3](https://github.com/bastean/codexgo/compare/v4.6.2...v4.6.3) (2024-08-19) + +### Chores + +- **deps:** upgrade ([347f3d3](https://github.com/bastean/codexgo/commit/347f3d39f662ce1babe7bd43615d045bd56ca551)) +- **go:** upgrade to go1.23.0 ([4e2471a](https://github.com/bastean/codexgo/commit/4e2471a3f081569fdcc2e44ebdead833c9f38ea8)) + +### Documentation + +- **readme:** add api and views in workflow section ([321f85d](https://github.com/bastean/codexgo/commit/321f85d6a0771ceaca843b1a44f81226d7223c25)) + +### Bug Fixes + +- **cucumber:** add glob paths to match steps with features ([d903906](https://github.com/bastean/codexgo/commit/d903906d89d5771b5dd95749eb80a418f899e32f)) +- **dockerfile:** add syntax parser directive ([7248ef4](https://github.com/bastean/codexgo/commit/7248ef424a0f43db58213b6d1ea5efba51c3bcdf)) +- **makefile:** copy required dependencies on init ([d98384e](https://github.com/bastean/codexgo/commit/d98384ed9f64e1df7ef6d431efbc5136277bf43e)) +- **server:** change redirection to avoid status override error ([3cd8e14](https://github.com/bastean/codexgo/commit/3cd8e14f317788c32b25d7b621c099ac7dbff256)) + +### Refactors + +- **domain:** rename save to create in user repository ([f4c52a0](https://github.com/bastean/codexgo/commit/f4c52a0ef0d19722d3ffb9d3252361daff9163ba)) +- **server:** add disclaimer about external links ([f958392](https://github.com/bastean/codexgo/commit/f9583923975afa9d87337828b4ebcd997af51835)) +- **server:** use a direct implementation of gin handlers ([19264a3](https://github.com/bastean/codexgo/commit/19264a3737e882fc0958dde70d7a2988b24b563d)) + +### Tests + +- **acceptance:** use panic wrap instead of fatal in playwright setup ([fb32f20](https://github.com/bastean/codexgo/commit/fb32f20c72877605cfd0c38774a3e353cc32adcf)) + +## [4.6.2](https://github.com/bastean/codexgo/compare/v4.6.1...v4.6.2) (2024-08-11) + +### Chores + +- **deps:** upgrade ([e6af62c](https://github.com/bastean/codexgo/commit/e6af62c36a5c3b93289fcc994ca726d5b835f7fb)) + +### Documentation + +- **readme:** add description about folders ([a1b4f98](https://github.com/bastean/codexgo/commit/a1b4f98683e2038b9664c7202892cc38db2c9603)) + +### Bug Fixes + +- **makefile:** register husky hooks on initialization ([50326c7](https://github.com/bastean/codexgo/commit/50326c7c828462a726a9d00e0998ebdc207e06bb)) +- **release-it:** update bumper out file ([ba534f0](https://github.com/bastean/codexgo/commit/ba534f0cc571c2d98f0c6918eb88946ea775345e)) + +### Refactors + +- **dockerfile:** remove redundant layers ([3c61205](https://github.com/bastean/codexgo/commit/3c6120585fb2b9bfd22389b279bc55575eed78d9)) +- **domain:** rename user repository ([8781bd1](https://github.com/bastean/codexgo/commit/8781bd12127ef161eba75d9b8df63f50375a8ee4)) +- **infrastructure:** use a struct for auth values in smtp ([e0a703f](https://github.com/bastean/codexgo/commit/e0a703fb7413052302cbfd92491e2994311668b4)) +- **infrastructure:** use user primitive struct as collection schema in mongo ([ec07756](https://github.com/bastean/codexgo/commit/ec077560f9353711baa71811bf5fa8ff18138606)) +- **scripts:** add beginning and end of regexp in syncenv ([0483d25](https://github.com/bastean/codexgo/commit/0483d25d3a0e5dfda5d1918141a54e867a4a289e)) + +### Styles + +- squash var, const and type in blocks ([23807d5](https://github.com/bastean/codexgo/commit/23807d5bfd35a9713176fb5fb32e0d9b80d68b94)) + +### Tests + +- throw panic in setup to avoid flaky tests ([2046fae](https://github.com/bastean/codexgo/commit/2046fae5bef9d091755c22786ba44b6f8eed5b36)) + +## [4.6.1](https://github.com/bastean/codexgo/compare/v4.6.0...v4.6.1) (2024-08-03) + +### Bug Fixes + +- **server:** relocate unreachable logs ([1f2df6a](https://github.com/bastean/codexgo/commit/1f2df6ab02ec362a27233344a9f2035e374bfa00)) + +## [4.6.0](https://github.com/bastean/codexgo/compare/v4.5.0...v4.6.0) (2024-08-03) + +### Chores + +- **deps:** upgrade ([240d8d4](https://github.com/bastean/codexgo/commit/240d8d4ed5334cb8b6561773752c9a83184101b4)) +- **docker:** add ignore file ([9bbaa59](https://github.com/bastean/codexgo/commit/9bbaa598143dfaabb69988a0c503c4550abe004e)) + +### Documentation + +- **readme:** add script to initialize repository from zip file ([78c843b](https://github.com/bastean/codexgo/commit/78c843b12e9bde9870bc758eef2f47783d592171)) + +### New Features + +- **devcontainer:** add ssh server ([5492305](https://github.com/bastean/codexgo/commit/54923055d13b4bde924b65dd10f7d8f95bfb6d49)) + +### Refactors + +- **docker:** rename default network ([494b3b4](https://github.com/bastean/codexgo/commit/494b3b4ad5796f3757ea03bf943c592772e837bc)) +- **makefile:** rename targets ([9093e2d](https://github.com/bastean/codexgo/commit/9093e2db7ba1f0f4d1e3b4ceb5b2167fc8665906)) +- **server:** separate views from api endpoints ([5fdd1ea](https://github.com/bastean/codexgo/commit/5fdd1ea6897493c06bf62f9199ca35cb6454adff)) + +## [4.5.0](https://github.com/bastean/codexgo/compare/v4.4.0...v4.5.0) (2024-07-30) + +### ⚠ BREAKING CHANGES + +- **deployments:** rename envs + +### Chores + +- change git ignore list ([f93dea2](https://github.com/bastean/codexgo/commit/f93dea2bb31c4a1d1dda834a832533a18ba44612)) +- **deps:** upgrade ([df92fda](https://github.com/bastean/codexgo/commit/df92fda92b054363249a9ef86440ad5910fff812)) +- **deps:** upgrade ([c994a97](https://github.com/bastean/codexgo/commit/c994a97ee5e635b37aa7181a22d97010ae22aaa0)) +- **makefile:** add set of rules to install tools ([94f0b8f](https://github.com/bastean/codexgo/commit/94f0b8fb8dcc7241bdd6c94013503bb9a9eed74a)) +- **mod:** upgrade ([31e32d2](https://github.com/bastean/codexgo/commit/31e32d2e250e58d5b1c5c93507ba33fe55bf33ab)) + +### Documentation + +- **readme:** add basic idiomatic ([1af2146](https://github.com/bastean/codexgo/commit/1af2146739b07d3f4682ea56bbefb914b1415d7b)) + +### New Features + +- **logger:** add colored outputs ([9e9d041](https://github.com/bastean/codexgo/commit/9e9d0415dfe982294405f5d5323ddc1fa8d7c22b)) +- **server:** add initial health check endpoint ([95f2117](https://github.com/bastean/codexgo/commit/95f2117797593780f2c77e6cd5900beb1be650b3)) +- **server:** add proxy check ([367773c](https://github.com/bastean/codexgo/commit/367773ce8ea859fe62c81b05e148be2dcb99101d)) + +### Refactors + +- change format of messages in errors ([dda8c9a](https://github.com/bastean/codexgo/commit/dda8c9ae2dfd919a15cfce597356e8026a20b8ce)) +- **deployments:** rename envs ([a3186bd](https://github.com/bastean/codexgo/commit/a3186bd899904d237a20e347940115796e22702f)) +- **dockerfile:** use makefile targets to install the tools ([c77f092](https://github.com/bastean/codexgo/commit/c77f0926af64ec0dc9b6240c61f1a05d27dbdb9e)) +- rename functions according to their layer ([e37b64c](https://github.com/bastean/codexgo/commit/e37b64c6a7744c81f995f821dbbed91b87085dc1)) +- **scripts:** reuse command execution in upgrade ([c48eec6](https://github.com/bastean/codexgo/commit/c48eec66c1143917cfc750fc628407d416246479)) +- **server:** change error handling ([a789393](https://github.com/bastean/codexgo/commit/a789393f07ce92914c27096cdaee7a745de2aba3)) +- **service:** organize envs ([71f4f4c](https://github.com/bastean/codexgo/commit/71f4f4ca29b9c6449612be18c990d8a6592cdece)) +- **service:** use aliases of context types ([51d7701](https://github.com/bastean/codexgo/commit/51d770172f757a4283bed9434d3c13cb8f89dabb)) + +### Tests + +- **acceptance:** assert errors directly ([6471fe2](https://github.com/bastean/codexgo/commit/6471fe2a71f6ec9c235c53fb880bb422e9724b20)) + +## [4.4.0](https://github.com/bastean/codexgo/compare/v4.3.1...v4.4.0) (2024-07-14) + +### ⚠ BREAKING CHANGES + +- **context:** rename packages +- **infrastructure:** rename packages +- rename envs +- add internal folder to manage apps and services + +### Chores + +- **deps:** upgrade dependencies ([dd29c51](https://github.com/bastean/codexgo/commit/dd29c5141e6f43b8fc9c4cb52806074d64cd6c5a)) + +### Documentation + +- **readme:** add more details about the interaction between layers ([99476ba](https://github.com/bastean/codexgo/commit/99476ba7c1d9f01bc8d42d59f5a417c1c43b59c2)) + +### New Features + +- **server:** show proxy port when running ([42c84ed](https://github.com/bastean/codexgo/commit/42c84edb2a2d4f37245b31da512e8e4f924a9fd8)) + +### Refactors + +- add internal folder to manage apps and services ([6081521](https://github.com/bastean/codexgo/commit/6081521f2f4496fcc4b3e162c31e5f9bb8b8c265)) +- **cmd:** stop apps before services ([0b52af7](https://github.com/bastean/codexgo/commit/0b52af71e25e7d0c2e98c0fb7c42cdd9f0148b66)) +- **context:** rename packages ([07f39eb](https://github.com/bastean/codexgo/commit/07f39eb8b477460c3ba15ee99fd893e8e9384232)) +- **context:** replace use of generic models with specific ones ([6ee85b2](https://github.com/bastean/codexgo/commit/6ee85b2aeb12d037e639cdd20c6696b38ae72349)) +- **domain:** add err prefix to bubble errors ([814a73b](https://github.com/bastean/codexgo/commit/814a73b55118751a5d3c7db77a3aa3fd364c57cb)) +- **infrastructure:** rename packages ([aa6b04d](https://github.com/bastean/codexgo/commit/aa6b04d42348cec42425eea5375b63328854eac1)) +- rename envs ([12ab31d](https://github.com/bastean/codexgo/commit/12ab31d7aeadb6129df463f558add5896b519a8b)) + +### Tests + +- **infrastructure:** add assertions for missing mongo errors ([d42e73e](https://github.com/bastean/codexgo/commit/d42e73e45d8b781b9b88c52edf6d7528e4effe4e)) + +## [4.3.1](https://github.com/bastean/codexgo/compare/v4.3.0...v4.3.1) (2024-07-01) + +### Chores + +- **deps:** upgrade dependencies ([1011a81](https://github.com/bastean/codexgo/commit/1011a814c472f1d00b75aa125e05f8b21721db8d)) + +### Bug Fixes + +- **makefile:** remove previous production docker image ([bcd39a0](https://github.com/bastean/codexgo/commit/bcd39a0d1b51eb6314e59c6239454d98dfeaa350)) +- **templ:** resolve imported and not used error ([84cbd69](https://github.com/bastean/codexgo/commit/84cbd69f90eccc3909e0ae620876bc3a1729acab)) + +## [4.3.0](https://github.com/bastean/codexgo/compare/v4.2.1...v4.3.0) (2024-06-26) + +### Chores + +- **deps:** upgrade dependencies ([bce72d8](https://github.com/bastean/codexgo/commit/bce72d872897ad527dd3e435fe45fe5f93300d81)) +- **deps:** upgrade jwt to v5 ([18054b7](https://github.com/bastean/codexgo/commit/18054b747b8250e7a169359dc1f54287328d0edc)) + +### Documentation + +- add scanners ([a34ea61](https://github.com/bastean/codexgo/commit/a34ea616ff1425c3053115df604e64ef9609e283)) + +### New Features + +- add trivy and osv scanners ([6fe3c53](https://github.com/bastean/codexgo/commit/6fe3c53255d3fb68dbbda985a0c15e7b9b68ae5c)) + +### Refactors + +- **context:** change domain message components ([157ef5b](https://github.com/bastean/codexgo/commit/157ef5bcd3a54c9784ddcdd6339e9223da735a38)) +- **context:** rename variables in value objects ([c8f46a1](https://github.com/bastean/codexgo/commit/c8f46a1e857c25d38a72da5a9f30273c8dc64e3d)) +- **scripts:** change panic on error ([4577790](https://github.com/bastean/codexgo/commit/4577790af035df66e18aa96ee8289c30409a1687)) +- **server:** rename service logs ([65bd07c](https://github.com/bastean/codexgo/commit/65bd07c900686326c91d5fba163c501348a8589e)) +- **server:** reorganize services ([f559715](https://github.com/bastean/codexgo/commit/f5597153bd121cce16d77aecba2cf0e268bcf1ce)) + +### Tests + +- **context:** add assertion for duplication error in mongo ([201fd53](https://github.com/bastean/codexgo/commit/201fd53f5970546dddaf62c2b21d50a35841052c)) +- **context:** add assertion for omitted json errors ([a08ea38](https://github.com/bastean/codexgo/commit/a08ea38efd3fa0d191505f48de571a234c9b2217)) + +## [4.2.1](https://github.com/bastean/codexgo/compare/v4.2.0...v4.2.1) (2024-06-19) + +### Bug Fixes + +- add boolean format verb in strings ([e317911](https://github.com/bastean/codexgo/commit/e317911d22e1798a4bc0a1c917089b06d8228a35)) +- remove default format verb in strings ([57beb5e](https://github.com/bastean/codexgo/commit/57beb5e3339a6ac9685e47bd2c798fdcccf619b2)) + +## [4.2.0](https://github.com/bastean/codexgo/compare/v4.1.1...v4.2.0) (2024-06-17) + +### Chores + +- **deps:** upgrade dependencies ([7b19ee7](https://github.com/bastean/codexgo/commit/7b19ee7dee15d14a7fad328977d090c031ef2964)) + +### New Features + +- **context:** add handling of omitted errors ([f70c276](https://github.com/bastean/codexgo/commit/f70c2767a368859560c1c2986411384ee36ae92e)) + +### Refactors + +- add default format verb to strings ([c459caa](https://github.com/bastean/codexgo/commit/c459caaf4c6fb7c5aede730caad10ab0093e3a3e)) +- change panic on error ([1fc83fa](https://github.com/bastean/codexgo/commit/1fc83fa7b6433059e098bbe8a21762b7eb95000a)) +- **context:** remove notify module ([064815f](https://github.com/bastean/codexgo/commit/064815f9efb7b75638c4f2d88efe1a27cacecc80)) +- **context:** remove redundant details from type names ([27a666a](https://github.com/bastean/codexgo/commit/27a666a11bf7232df9d9ba34c20f1d15e03abade)) + +### Tests + +- **context:** add handling of unexpected errors in mothers to avoid flaky tests ([2fbea22](https://github.com/bastean/codexgo/commit/2fbea223fada03944b1deb6a1b83f2f7df879e93)) + +## [4.1.1](https://github.com/bastean/codexgo/compare/v4.1.0...v4.1.1) (2024-06-12) + +### Bug Fixes + +- **makefile:** add pipefail to return an error when a test fails ([5b4c26e](https://github.com/bastean/codexgo/commit/5b4c26e4621fec259eb1b6cfa0bd263534b50588)) + +## [4.1.0](https://github.com/bastean/codexgo/compare/v4.0.0...v4.1.0) (2024-06-10) + +### Chores + +- **deps:** upgrade dependencies ([93fc426](https://github.com/bastean/codexgo/commit/93fc4264ee2f2937e07e9a8f9c96156df4dfb4f1)) + +### Documentation + +- **readme:** add basic layers workflow ([b6f6d5d](https://github.com/bastean/codexgo/commit/b6f6d5d0f8b6bb75759a8a0744f86bd5abc44893)) + +### New Features + +- **makefile:** add tee in test rules ([1d21d7a](https://github.com/bastean/codexgo/commit/1d21d7a31fac96db750c9266e181f93765ca1089)) + +### Bug Fixes + +- **dockerfile:** update air module name ([71bc376](https://github.com/bastean/codexgo/commit/71bc376c7a6e834d16eaf10684806ca652bd3e51)) + +### Refactors + +- add type alias ([f55bb9d](https://github.com/bastean/codexgo/commit/f55bb9d1fbe3c933c1bb48e6885270c92e69beee)) +- **context:** add pointer to search criteria type ([8648a18](https://github.com/bastean/codexgo/commit/8648a184464c355d5b6216a4cb6a2f58c4bc1b95)) +- **context:** change empty type from struct to interface ([4e5dcf0](https://github.com/bastean/codexgo/commit/4e5dcf0152a5eec35818edf90030ae449037e0a2)) +- **context:** change errors in shared module ([47fe621](https://github.com/bastean/codexgo/commit/47fe62172d93792694beef6df3145502690e8d6a)) +- **context:** change parameters to use primitive type in user module ([db8fc5b](https://github.com/bastean/codexgo/commit/db8fc5b12b24968677f2a452e703a5af3192020f)) +- **context:** change updates in user module ([ba294af](https://github.com/bastean/codexgo/commit/ba294aff99ac5a6d35b2701531d97bf16f6191fd)) +- squash struct fields ([8ccc22c](https://github.com/bastean/codexgo/commit/8ccc22c0ed57d02e1717d723462673ee1ebc55d3)) + +### Tests + +- **context:** add more explicit test case names ([5027a31](https://github.com/bastean/codexgo/commit/5027a31a0fafcdbcac17ad09a04b557e145c5a55)) + +## [4.0.0](https://github.com/bastean/codexgo/compare/v3.0.1...v4.0.0) (2024-05-28) + +### ⚠ BREAKING CHANGES + +- **server:** decouple service initializations +- **context:** change notification system workflow +- **server:** change acceptance tests to work with the new ui +- **server:** add fomantic-ui +- **server:** change error handling from panic to wrapped errors +- **context:** change package names in shared module +- **context:** change integration tests to check for wrapped errors instead of panic +- **context:** change unit tests to check for wrapped errors instead of panic +- **context:** change error handling from panic to wrapped errors + +### Chores + +- change air config ([a3b2f94](https://github.com/bastean/codexgo/commit/a3b2f94cb9f1f5b69ab719ae09001bac8382e7b2)) +- change git ignore list ([122f7b2](https://github.com/bastean/codexgo/commit/122f7b2ba448cf79e741e5c7c3e3b7283a2dcaaf)) +- change go version in mod file ([95ac107](https://github.com/bastean/codexgo/commit/95ac107f7b6dee5618ec459c911ca07440521c04)) +- change makefile rules ([285b30b](https://github.com/bastean/codexgo/commit/285b30b7e1c88503681279e097d4a6e0abf8154c)) +- **deps:** upgrade dependencies ([f804fc8](https://github.com/bastean/codexgo/commit/f804fc8c0e22f660407e80c826811455d9d13303)) + +### Documentation + +- **readme:** add updated screenshots ([ffd6b17](https://github.com/bastean/codexgo/commit/ffd6b175b19292111ba5bff3611322c7ee8cdbb6)) +- **readme:** change description ([122b14c](https://github.com/bastean/codexgo/commit/122b14c69174c5de0f9cc0cac54e4b55ea3a25d2)) + +### New Features + +- **air:** enable live-reloading on the browser ([7714c38](https://github.com/bastean/codexgo/commit/7714c38cf0a74ef07dff07d232b98f462070a71a)) +- **context:** add json marshal error handler to error bubble ([68819fe](https://github.com/bastean/codexgo/commit/68819fe9521117adb43504105b90f91abecebce4)) +- **context:** add new terminal transport port adapter to notify module ([28fd1fe](https://github.com/bastean/codexgo/commit/28fd1fe865666b65f25d93e1f7b1895f2b40a998)) +- **scripts:** add copy-deps script ([79e2d73](https://github.com/bastean/codexgo/commit/79e2d73989674b9a2d62841db87da89ef4bd8564)) +- **server:** add accepts cookies nag ([682c370](https://github.com/bastean/codexgo/commit/682c370366139911fa145defa9127310503d86e9)) +- **server:** add cookies cleaning ([30d4b9a](https://github.com/bastean/codexgo/commit/30d4b9aca620098e1ed4b9c0c0501003570f8007)) +- **server:** add fomantic-ui ([738bf51](https://github.com/bastean/codexgo/commit/738bf5140c0dcb310c4effcbd3659720ba2c20a5)) +- **server:** add log files ([141001a](https://github.com/bastean/codexgo/commit/141001a2d0bf0269a25030597c45d3a2b7c2f891)) +- **server:** add missing error handlers ([99938f6](https://github.com/bastean/codexgo/commit/99938f6a5c00a47a5d4471d07354fe565a6c50f5)) +- **server:** add popup to inform about account status ([77eb4a9](https://github.com/bastean/codexgo/commit/77eb4a917e1487a3736da346064befa0ff3d35c8)) + +### Bug Fixes + +- add missing pointers ([b6b9343](https://github.com/bastean/codexgo/commit/b6b934305caecf51eea9c058e84d75cfaa2d353f)) +- **deps:** upgrade dependencies ([4574f31](https://github.com/bastean/codexgo/commit/4574f3147dff657eb1672a97d0acea236bf8d5c4)) +- **server:** add json unmarshal type error handler ([eb9eeb5](https://github.com/bastean/codexgo/commit/eb9eeb5e4442caf2abd07c294cd68a0c9db8f9b9)) + +### Refactors + +- add field names at struct initialization ([55c5de3](https://github.com/bastean/codexgo/commit/55c5de3902be83a9066b9867e9493ad4ebab6f87)) +- **context:** change error handling from panic to wrapped errors ([ec3245c](https://github.com/bastean/codexgo/commit/ec3245c9caf81562cfb8c2ae61aa16ee34b4d5e6)) +- **context:** change exchange to router in broker model ([be19870](https://github.com/bastean/codexgo/commit/be198705206d0f0370b73dc5ed8bb9cf1c3d3572)) +- **context:** change notification system workflow ([f7ec73c](https://github.com/bastean/codexgo/commit/f7ec73cd038337f63b792f1f2623285b7e0eb854)) +- **context:** change package names in shared module ([e26da1e](https://github.com/bastean/codexgo/commit/e26da1e123692559f9a84a2ad3f0e53c4a1b1743)) +- **context:** change time format in errors ([23362e4](https://github.com/bastean/codexgo/commit/23362e40d7ea9fafe2b83a120f3bbc6652644057)) +- **context:** change type name of shared errors ([61c9b93](https://github.com/bastean/codexgo/commit/61c9b93fcec544e6d95c4e3ecd76a0f49ba38e43)) +- **context:** rename folders using plural names instead of the prefix s in shared module ([fe5aabf](https://github.com/bastean/codexgo/commit/fe5aabf7b3815b60a48382076f7f453e065f15f2)) +- **context:** rename packages using plural names in shared module ([db66e1d](https://github.com/bastean/codexgo/commit/db66e1d7e9c62ed8600f048512c37ec30bcba4ef)) +- **makefile:** add MAKE variable to rules with a recursive recipe ([75e31a8](https://github.com/bastean/codexgo/commit/75e31a84e9b58b1723270bce738162240628e21d)) +- **makefile:** change target names of test rules ([f078581](https://github.com/bastean/codexgo/commit/f0785811deabe3ab8343185cb14ca97933c6341c)) +- rename files using flatcase ([28d3e5f](https://github.com/bastean/codexgo/commit/28d3e5fafad4cdbeed23a8c6bb51724e6e6f746e)) +- **scripts:** change commit message on upgrade script ([9b257a2](https://github.com/bastean/codexgo/commit/9b257a223f1c2cc22dfe9c7dc5b1764389f3f8f1)) +- **server:** add ui class in jquery component selectors ([3c1743e](https://github.com/bastean/codexgo/commit/3c1743ed59d0e35fe5b4d2e2e7d9a4e62066a4a5)) +- **server:** change broker service components to individual files ([93d3c29](https://github.com/bastean/codexgo/commit/93d3c29e4669be36e5ed2f196fdb4e1183314a72)) +- **server:** change error handling from panic to wrapped errors ([1e3d766](https://github.com/bastean/codexgo/commit/1e3d766be194b64960e302b83318a9929f104e5c)) +- **server:** change error messages in services ([0f6a21e](https://github.com/bastean/codexgo/commit/0f6a21e98a89347d721f32b611fdacd6b405430d)) +- **server:** decouple service initializations ([61961d2](https://github.com/bastean/codexgo/commit/61961d2327948df5b9611ff75034c28d9f34a859)) + +### Tests + +- **context:** add spaces between definitions in setup test ([4318ea2](https://github.com/bastean/codexgo/commit/4318ea27f6cac20154489c55917b9d639bd54fe0)) +- **context:** change integration tests to check for wrapped errors instead of panic ([6bb93ac](https://github.com/bastean/codexgo/commit/6bb93ac315e0049a2407952406e8349886274b2a)) +- **context:** change time on expected error messages ([56137d6](https://github.com/bastean/codexgo/commit/56137d695a6663e18272db70c1d98dcf97c03140)) +- **context:** change unit tests to check for wrapped errors instead of panic ([971b9de](https://github.com/bastean/codexgo/commit/971b9de188f998f9b6ecdec5435375be46789c9f)) +- **server:** change acceptance tests to work with the new ui ([8df4c59](https://github.com/bastean/codexgo/commit/8df4c59c9c280d7c7a55285fa662b682b2df9469)) + +## [3.0.1](https://github.com/bastean/codexgo/compare/v3.0.0...v3.0.1) (2024-04-08) + +### Bug Fixes + +- **deps:** upgrade dependencies ([bd92cf7](https://github.com/bastean/codexgo/commit/bd92cf74fced77cb9011171e60f15d687ddc94f7)) +- **makefile:** add phony target ([3c33a90](https://github.com/bastean/codexgo/commit/3c33a9005396067e0a2c130d78648a41bc677f73)) +- **makefile:** remove init-ci rule ([3311e14](https://github.com/bastean/codexgo/commit/3311e144798aaff6dfe34df1c2c8aa9751f3ca68)) + +### Refactors + +- **makefile:** change rules order ([95c6170](https://github.com/bastean/codexgo/commit/95c6170e4719d0702efe2ed75197c42cd3103494)) + +## [3.0.0](https://github.com/bastean/codexgo/compare/v2.0.1...v3.0.0) (2024-04-04) + +### Documentation + +- **readme:** add features ([6d36f5d](https://github.com/bastean/codexgo/commit/6d36f5d75dfc6e1e3cf9cb50ca01d6f7ab1a4b7a)) + +### New Features + +- add account confirmation via email ([66f7b6e](https://github.com/bastean/codexgo/commit/66f7b6eda53e2f3ea897603c032e85f51fe6cf83)) +- add event-driven architecture using rabbitmq ([1fd11cb](https://github.com/bastean/codexgo/commit/1fd11cb1b1b9096dc2aafccd2da8982d6d041279)) +- add example env demo file ([c288d3c](https://github.com/bastean/codexgo/commit/c288d3ccdd7e4d348b915f22c9fa0236df7de247)) +- add gracefully close infrastructure connections ([fb91c9a](https://github.com/bastean/codexgo/commit/fb91c9a569d7f2d6be67e983e19bb53ec5cb5191)) + +### Bug Fixes + +- **deps:** upgrade dependencies ([a27389f](https://github.com/bastean/codexgo/commit/a27389f51cfc9b37d6b11dcc1013c2e02be84ea4)) +- remove files generated by templ ([0adc9c6](https://github.com/bastean/codexgo/commit/0adc9c6cd570b672f8f9719ee0f3691b895804fd)) + +### Refactors + +- change env handling in context to app ([f395933](https://github.com/bastean/codexgo/commit/f395933288ba2ad6fbb95eb683faa7195ebad890)) +- change templ components ([e54c18a](https://github.com/bastean/codexgo/commit/e54c18a8421a1f5a62bb7ef0e2e58f90f2b50f4b)) + +### Tests + +- add individual execution of unit, integration and acceptance tests ([4dc646f](https://github.com/bastean/codexgo/commit/4dc646f52794c0ad80803ce95900c0bf402029fd)) +- remove shared value objects ([618ab5c](https://github.com/bastean/codexgo/commit/618ab5c990f2c54ec574380f54778fb64757ea2a)) + +## [2.0.1](https://github.com/bastean/codexgo/compare/v2.0.0...v2.0.1) (2024-03-13) + +### Bug Fixes + +- **deps:** upgrade dependencies ([4e3f621](https://github.com/bastean/codexgo/commit/4e3f621bf8b3833ef2cd4d7bbe877cf5d38a81ac)) + +### Refactors + +- change domain models ([f80911a](https://github.com/bastean/codexgo/commit/f80911acf48a9bfb115d3328a7834babfa123b02)) + +## [2.0.0](https://github.com/bastean/codexgo/compare/v1.5.0...v2.0.0) (2024-03-02) + +### ⚠ BREAKING CHANGES + +- add standard project layout + +### Bug Fixes + +- **deps:** upgrade dependencies ([f11b15f](https://github.com/bastean/codexgo/commit/f11b15f77899ab50ae0ac744dd84346cb71a7760)) + +### Refactors + +- add standard project layout ([307089c](https://github.com/bastean/codexgo/commit/307089c56975716fb6788e6fafd06ffa8b42f620)) + +## [1.5.0](https://github.com/bastean/codexgo/compare/v1.4.0...v1.5.0) (2024-02-18) + +### New Features + +- add script to sync .env\* files ([e7fcc0b](https://github.com/bastean/codexgo/commit/e7fcc0b6355e5abf00a97526e7becb111cdf2dda)) + +### Bug Fixes + +- **deps:** upgrade dependencies ([fecaafa](https://github.com/bastean/codexgo/commit/fecaafa9bf35e6a5fa71ae0468845bd32bef26ea)) + +## [1.4.0](https://github.com/bastean/codexgo/compare/v1.3.1...v1.4.0) (2024-02-15) + +### New Features + +- add commit message types to include in the changelog ([db06cf9](https://github.com/bastean/codexgo/commit/db06cf95d6d637f097a6745d04302b8f272a50a6)) + +### Bug Fixes + +- **deps:** upgrade dependencies ([80c2256](https://github.com/bastean/codexgo/commit/80c22563516b5da15ea07475fbc94c4fcbffd5c6)) + +## [1.3.1](https://github.com/bastean/codexgo/compare/v1.3.0...v1.3.1) (2024-02-14) + +### Bug Fixes + +- **actions:** upgrade go setup action ([da7bc21](https://github.com/bastean/codexgo/commit/da7bc213a052d088efaac6b20c5ec5ad92f4d037)) +- change live reload ([2f97bdb](https://github.com/bastean/codexgo/commit/2f97bdbe0675a747ac4eddcfe99632dcf0803b0f)) + +## [1.3.0](https://github.com/bastean/codexgo/compare/v1.2.0...v1.3.0) (2024-02-06) + +### Features + +- **actions:** add upgrade workflow ([e2d62d4](https://github.com/bastean/codexgo/commit/e2d62d4d76e56e0dfaabe0cbd474ef23ee1e5687)) +- add script to upgrade dependencies ([a7cd088](https://github.com/bastean/codexgo/commit/a7cd088099d336526e00c6187a835f9938e48a55)) +- **backend:** add secure middleware ([370db08](https://github.com/bastean/codexgo/commit/370db087b6df9ce1aaa3fa2e5589abc9756ec9b2)) + +### Bug Fixes + +- **actions:** add commit push to upgrade workflow ([9ea06db](https://github.com/bastean/codexgo/commit/9ea06dbfdb1f2af22f187734d757fe2ad8b0e88a)) +- **deps:** upgrade dependencies ([811345c](https://github.com/bastean/codexgo/commit/811345c603d2b07ed76f83620fc6386ea90d1861)) +- **deps:** upgrade dependencies ([c99be30](https://github.com/bastean/codexgo/commit/c99be30ae77f766ca09dece90a627f657f8458c3)) + +## [1.2.0](https://github.com/bastean/codexgo/compare/v1.1.0...v1.2.0) (2024-01-28) + +### Features + +- **backend:** add rate limiter middleware ([a6c1b2b](https://github.com/bastean/codexgo/commit/a6c1b2b2a484d0b4ac63364b76c1ba18f8c3e4b3)) + +### Bug Fixes + +- **deps:** upgrade modules dependencies ([d9851aa](https://github.com/bastean/codexgo/commit/d9851aaeb9ff510148935043ab446bea52e3dc26)) +- remove go vet from lint-staged ([3869cbf](https://github.com/bastean/codexgo/commit/3869cbf84fb83bc105b16be0fb6f1a03ab830e9f)) + +## [1.1.0](https://github.com/bastean/codexgo/compare/v1.0.0...v1.1.0) (2024-01-22) + +### Features + +- **actions:** add brew setup ([ef7a00d](https://github.com/bastean/codexgo/commit/ef7a00de57e7cf524223f6e4ced5f7bf2ad71e55)) +- add go vet on lint-staged ([8c52de4](https://github.com/bastean/codexgo/commit/8c52de4ace6d34c2174fe8f03c35e84b6a4040a5)) +- add upx to compress binaries ([9d4e926](https://github.com/bastean/codexgo/commit/9d4e926a3b764f6fe2e49009fb69adc127acb7ea)) +- **devcontainer:** add brew to simplify installation of tools ([8c77ed4](https://github.com/bastean/codexgo/commit/8c77ed45692b6303fcb6235b4ddb612d4e175505)) +- **makefile:** add go mod tidy on lint rule ([d203639](https://github.com/bastean/codexgo/commit/d203639765560e1e375b77b9759bed581c2176ab)) + +### Bug Fixes + +- **docker:** add optimization to compose ([0730183](https://github.com/bastean/codexgo/commit/0730183bfbc522f0c5278a733e63b346fbe41044)) + +## [1.0.0](https://github.com/bastean/codexgo/compare/v0.1.1...v1.0.0) (2024-01-17) + +### ⚠ BREAKING CHANGES + +- **readme:** Ready for v1 + +### Features + +- add codexgo logos ([7ff0641](https://github.com/bastean/codexgo/commit/7ff0641a5db2df5f180242e3d05d93c1ba0cfc92)) +- add trufflehog scan on lint-staged ([bdc473c](https://github.com/bastean/codexgo/commit/bdc473c56a446e0268c1ed02222af2a37185c244)) +- **ci:** add tests job to workflow ([c033f54](https://github.com/bastean/codexgo/commit/c033f5429ddbe07f55281a921b706e6820537ffa)) +- **devcontainer:** add cucumber extension ([fabb6d8](https://github.com/bastean/codexgo/commit/fabb6d8e990b87a71f0152cdeb43b6c28f3cd878)) +- **docker:** add production compose ([4963296](https://github.com/bastean/codexgo/commit/49632964e8a238fd676204cd4eb0bff03a959ac7)) + +### Bug Fixes + +- **backend:** add responsive to alerts ([fc1e4c8](https://github.com/bastean/codexgo/commit/fc1e4c80ba071edc7bfaf39a43bae4aaad8f5b1d)) + +### Documentation + +- **readme:** add contributing section ([54e95f6](https://github.com/bastean/codexgo/commit/54e95f65a5deddd73e1021ad520c848a75ca29cc)) + +## [0.1.1](https://github.com/bastean/codexgo/compare/v0.1.0...v0.1.1) (2024-01-07) + +## 0.1.0 (2024-01-07) + +### Features + +- **backend:** add basis to use htmx with tailwindcss ([5f260b5](https://github.com/bastean/codexgo/commit/5f260b5a594c0eaa50324d04f715f614145f7adc)) +- **backend:** add crud endpoints ([08957ba](https://github.com/bastean/codexgo/commit/08957ba38446d9c3d52e75d225f5b77c1541c7f3)) +- **backend:** add development dockerfile ([a8cef51](https://github.com/bastean/codexgo/commit/a8cef51c8f158fac22c71a567441b3efb49abfc8)) +- **backend:** add pwa ([a370906](https://github.com/bastean/codexgo/commit/a3709064ba027b9c2e60cd157de55c95e41802a3)) +- **context|backend:** add authentication to protected endpoints ([b582c11](https://github.com/bastean/codexgo/commit/b582c112f11e9a206fd037a2ecd7ea2bafa252ce)) +- **context|backend:** add password hashing ([8264127](https://github.com/bastean/codexgo/commit/82641276144048800e1a99ac0806f3a1402f98a7)) +- **context:** add basis to run use cases ([fa28f1f](https://github.com/bastean/codexgo/commit/fa28f1f87471e6c84dccdcebd35fc198bb46b96d)) +- **context:** add crud use cases ([d503539](https://github.com/bastean/codexgo/commit/d5035397c7485e2826e4ed4cf594db2f32ef7145)) +- **context:** add mongo repository adapter ([f25a793](https://github.com/bastean/codexgo/commit/f25a7931fab225edebc6e03a4f6f0a124a8ab05d)) +- **devcontainer:** add prettier extension ([d833c1b](https://github.com/bastean/codexgo/commit/d833c1b62defdc6407534662358c89396948e7dc)) + +### Bug Fixes + +- **ci:** upgrade actions ([3054b85](https://github.com/bastean/codexgo/commit/3054b85e405293668d0e2647b584e7cb0f815710)) +- **release:** change manifest path ([05918f0](https://github.com/bastean/codexgo/commit/05918f0961fed086665c3e8572efcee5cdf9a025)) diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..3c8a03b --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) Bastean + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..21726c1 --- /dev/null +++ b/Makefile @@ -0,0 +1,303 @@ +.PHONY: * + +#*------------VARS------------ + +#*______URL______ + +url-server = http://localhost:8080 +url-github = https://github.com/bastean/codexgo + +#*______Go______ + +go-tidy = go mod tidy -e + +#*______Node______ + +npx = npx --no -- +npm-ci = npm ci --legacy-peer-deps + +release-it = ${npx} release-it -V +release-it-dry = ${npx} release-it -V -d --no-git.requireCleanWorkingDir + +#*______Bash______ + +bash = bash -o pipefail -c + +#*______Git______ + +git-reset-hard = git reset --hard HEAD + +#*______Docker______ + +docker-rm-vol = docker volume rm -f +docker-rm-img = docker rmi -f + +compose = cd deployments && docker compose +compose-env = ${compose} --env-file + +#*------------RULES------------ + +#*______Upgrade______ + +upgrade-managers: + #? sudo apt update && sudo apt upgrade -y + npm upgrade -g + +upgrade-go: + go get -t -u ./cmd/... ./internal/... ./pkg/... ./scripts/... + +copydeps: + go run ./scripts/copydeps + +upgrade-node: + ${npx} ncu -ws -u + npm i --legacy-peer-deps + $(MAKE) copydeps + +upgrade-reset: + ${git-reset-hard} + ${npm-ci} + +upgrade: + go run ./scripts/upgrade + +#*______Install______ + +install-scanners: + curl -sSfL https://raw.githubusercontent.com/trufflesecurity/trufflehog/main/scripts/install.sh | sudo sh -s -- -b /usr/local/bin v3.63.11 + curl -sSfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sudo sh -s -- -b /usr/local/bin v0.52.2 + go install github.com/google/osv-scanner/cmd/osv-scanner@latest + +install-linters: + go install honnef.co/go/tools/cmd/staticcheck@latest + npm i -g prettier + +install-tools-dev: install-scanners install-linters + go install github.com/air-verse/air@latest + go install github.com/a-h/templ/cmd/templ@latest + +install-tools-test: + go run github.com/playwright-community/playwright-go/cmd/playwright@latest install chromium --with-deps + npm i -g concurrently wait-on + +install-tooling: install-tools-dev install-tools-test + +install-tooling-ci: install-tools-dev + +#*______Download______ + +download-dependencies: + go mod download + ${npm-ci} + +#*______Generate______ + +generate-required: + go generate ./... + find . -name "*_templ.go" -type f -delete + templ generate + +#*______Restore______ + +restore: + ${npx} husky init + git restore . + +#*______Init______ + +init: upgrade-managers install-tooling download-dependencies copydeps generate-required restore + +init-ci: upgrade-managers install-tooling-ci download-dependencies generate-required restore + +genesis: + git init + git add . + $(MAKE) init + +#*______Lint/Format______ + +lint: generate-required + go mod tidy + gofmt -l -s -w . + ${npx} prettier --ignore-unknown --write . + templ fmt . + +lint-check: + staticcheck ./... + ${npx} prettier --check . + +#*______Scan______ + +scan-leaks-local: + sudo trufflehog git file://. --only-verified + trivy repo --scanners secret . + +scan-leaks-remote: + sudo trufflehog git ${url-github} --only-verified + trivy repo --scanners secret ${url-github} + +scan-vulns-local: + osv-scanner --call-analysis=all -r . + trivy repo --scanners vuln . + +scan-misconfigs-local: + trivy repo --scanners misconfig . + +scan-leaks: scan-leaks-local scan-leaks-remote + +scan-vulns: scan-vulns-local + +scan-misconfigs: scan-misconfigs-local + +scans: scan-leaks scan-vulns scan-misconfigs + +#*______Test______ + +test-sut: + air + +test-clean: generate-required + go clean -testcache + mkdir -p test/report + +test-codegen: + ${npx} playwright codegen ${url-server} + +test-sync: + ${npx} concurrently -s first -k --names 'SUT,TEST' '$(MAKE) test-sut' '${npx} wait-on -l ${url-server}/health && $(TEST_SYNC)' + +test-unit: test-clean + ${bash} 'go test -v -cover ./pkg/context/... -run TestUnit.* |& tee test/report/unit.report.log' + +test-integration: test-clean + ${bash} 'go test -v -cover ./pkg/context/... -run TestIntegration.* |& tee test/report/integration.report.log' + +test-acceptance-sync: + ${bash} 'SUT_URL="${url-server}" go test -v -cover ./internal/app/... -run TestAcceptance.* |& tee test/report/acceptance.report.log' + +test-acceptance: test-clean + TEST_SYNC="$(MAKE) test-acceptance-sync" $(MAKE) test-sync + +tests-sync: + ${bash} 'SUT_URL="${url-server}" go test -v -cover ./... |& tee test/report/report.log' + +tests: test-clean + TEST_SYNC="$(MAKE) tests-sync" $(MAKE) test-sync + +#*______Release______ + +release: + ${release-it} + +release-alpha: + ${release-it} --preRelease=alpha + +release-beta: + ${release-it} --preRelease=beta + +release-ci: + ${release-it} --ci --no-git.requireCleanWorkingDir $(OPTIONS) + +release-dry: + ${release-it-dry} + +release-dry-version: + ${release-it-dry} --release-version + +release-dry-changelog: + ${release-it-dry} --changelog + +#*______Build______ + +build: lint + rm -rf build/ + go build -ldflags="-s -w" -o build/codexgo ./cmd/codexgo + +#*______ENV______ + +syncenv-reset: + ${git-reset-hard} + +syncenv: + cd deployments && go run ../scripts/syncenv + +#*______Git______ + +commit: + ${npx} cz + +WARNING-git-forget: + git rm -r --cached . + git add . + +WARNING-git-genesis: + git clean -e .env* -fdx + ${git-reset-hard} + $(MAKE) init + +#*______Docker______ + +docker-usage: + docker system df + +docker-it: + docker exec -it $(ID) bash + +compose-dev-down: + ${compose-env} .env.dev down + ${docker-rm-vol} codexgo-database-mongodb-dev + +compose-dev: compose-dev-down + ${compose-env} .env.dev up + +compose-test-down: + ${compose-env} .env.test down + ${docker-rm-vol} codexgo-database-mongodb-test + +compose-test-integration: compose-test-down + ${compose-env} .env.test --env-file .env.test.integration up --exit-code-from codexgo + +compose-test-acceptance: compose-test-down + ${compose-env} .env.test --env-file .env.test.acceptance up --exit-code-from codexgo + +compose-tests: compose-test-down + ${compose-env} .env.test up --exit-code-from codexgo + +compose-prod-down: + ${compose-env} .env.prod down + ${docker-rm-img} codexgo + +compose-prod: compose-prod-down + ${compose-env} .env.prod up --exit-code-from codexgo + +demo-down: + ${compose-env} .env.demo down + +demo: demo-down + ${compose-env} .env.demo up --exit-code-from codexgo + +compose-down: compose-dev-down compose-test-down compose-prod-down demo-down + +WARNING-docker-prune-soft: + docker system prune + $(MAKE) compose-down + $(MAKE) docker-usage + +WARNING-docker-prune-hard: + docker system prune --volumes -a + $(MAKE) compose-down + $(MAKE) docker-usage + +#*______Devcontainer______ + +devcontainer: + ${bash} 'echo -e "$(USER_PASSWORD)\n$(USER_PASSWORD)" | sudo passwd vscode' + +connect: + ssh -p 2222 -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null -o GlobalKnownHostsFile=/dev/null vscode@localhost + +#*______Fix______ + +fix-dev: upgrade-go install-tools-dev + +fix-test: upgrade-go install-tools-test diff --git a/README.md b/README.md new file mode 100644 index 0000000..1fb6667 --- /dev/null +++ b/README.md @@ -0,0 +1,534 @@ +

+ + + +[![README Logo](assets/readme/logo.png)](https://github.com/bastean/codexgo) + +

+ +
+ +> Example CRUD project applying Hexagonal Architecture, Domain-Driven Design (DDD), Event-Driven Architecture (EDA), Command Query Responsibility Segregation (CQRS), Behavior-Driven Development (BDD), Continuous Integration (CI), and more... in Go. + +
+ +
+ +
+ +[![License MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) +[![Go Report Card](https://goreportcard.com/badge/github.com/bastean/codexgo/v4)](https://goreportcard.com/report/github.com/bastean/codexgo/v4) +[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](https://github.com/commitizen/cz-cli) +[![Release It!](https://img.shields.io/badge/%F0%9F%93%A6%F0%9F%9A%80-release--it-orange.svg)](https://github.com/release-it/release-it) + +
+ +
+ +[![Upgrade workflow](https://github.com/bastean/codexgo/actions/workflows/upgrade.yml/badge.svg)](https://github.com/bastean/codexgo/actions/workflows/upgrade.yml) +[![CI workflow](https://github.com/bastean/codexgo/actions/workflows/ci.yml/badge.svg)](https://github.com/bastean/codexgo/actions/workflows/ci.yml) +[![Release workflow](https://github.com/bastean/codexgo/actions/workflows/release.yml/badge.svg)](https://github.com/bastean/codexgo/actions/workflows/release.yml) + +
+ +
+ +[![Go Reference](https://pkg.go.dev/badge/github.com/bastean/codexgo/v4.svg)](https://pkg.go.dev/github.com/bastean/codexgo/v4) +[![GitHub Releases](https://img.shields.io/github/v/release/bastean/codexgo.svg)](https://github.com/bastean/codexgo/releases) + +
+ +## Showcase + +
+ + + + + + + + + + + +
+ +## CLI + +### Installation + +```bash +go install github.com/bastean/codexgo/v4/cmd/codexgo@latest +``` + +### Usage + +> [!NOTE] +> +> - We need to create an `.env` file where we have our own values defined. +> - In the [.env.example.cli](deployments/.env.example.cli) file, we can see the values that can be used. +> - By omitting `CODEXGO_SMTP_*`, the link to confirm the account is sent through the Terminal. +> - _"Hi \, please confirm your account through this link: \"_ +> - We can define our own **SMTP** configuration by simply modifying the `CODEXGO_SMTP_*` variables, then we will be able to receive the links by mail. + +```bash +codexgo -h +``` + +```text + _________ ________________ +_____________ ______ /_____ ____ __ __ ____/__ __ \ +_ ___/_ __ \_ __ / _ _ \__ |/_/ _ / __ _ / / / +/ /__ / /_/ // /_/ / / __/__> < / /_/ / / /_/ / +\___/ \____/ \__,_/ \___/ /_/|_| \____/ \____/ + +Example CRUD project applying Hexagonal Architecture, DDD, EDA, CQRS, BDD, CI, and more... in Go. + +Usage: codexgo [flags] + + -env string + Path to ENV file (required) +``` + +## Docker + +### Usage (Demo) + +> [!NOTE] +> +> - [System Requirements](#locally) +> - In the Demo version, the link to confirm the account is sent through the Terminal. +> - _"Hi \, please confirm your account through this link: \"_ +> - We can define our own **SMTP** configuration in the [.env.demo](deployments/.env.demo) file by simply modifying the `CODEXGO_SMTP_*` variables, then we will be able to receive the links by mail. + +```bash +make demo +``` + +## Features + +### Project Layout + +- Based on [Standard Go Project Layout](https://github.com/golang-standards/project-layout). + +### Git + +- Hooks managed by [husky](https://github.com/typicode/husky): + - Pre-Push: + - Scanning Repository for leaks using [TruffleHog CLI](https://github.com/trufflesecurity/trufflehog) and [Trivy](https://github.com/aquasecurity/trivy) + - Pre-Commit: [lint-staged](https://github.com/lint-staged/lint-staged) + - Scanning files for leaks using [TruffleHog CLI](https://github.com/trufflesecurity/trufflehog?tab=readme-ov-file#8-scan-individual-files-or-directories) + - Formatting + - Commit-Msg: [commitlint](https://github.com/conventional-changelog/commitlint) + - Check [Conventional Commits](https://www.conventionalcommits.org) rules +- Commit message helper using [Commitizen](https://github.com/commitizen/cz-cli). + - Interactive prompt that allows you to write commits following the [Conventional Commits](https://www.conventionalcommits.org) rules: + ```bash + make commit + ``` + +### Linting/Formatting Tools + +- Go: **staticcheck** and **gofmt**. +- templ: **templ fmt**. +- Gherkin: **Cucumber extension**. +- Others: **Prettier cli/extension**. + +### Scanners + +- [TruffleHog CLI](https://github.com/trufflesecurity/trufflehog): Secrets. +- [Trivy](https://github.com/aquasecurity/trivy): Secrets, Vulnerabilities and Misconfigurations. +- [OSV-Scanner](https://github.com/google/osv-scanner): Vulnerabilities. + +### Testing Packages + +- Random data generator: [Gofakeit](https://github.com/brianvoe/gofakeit). +- Unit/Integration: [Testify](https://github.com/stretchr/testify). +- Acceptance: [Testify](https://github.com/stretchr/testify), [Godog (Cucumber)](https://github.com/cucumber/godog) and [Playwright](https://github.com/playwright-community/playwright-go). + +### Releases + +- Automatically managed by [Release It!](https://github.com/release-it/release-it): + - Before/After Hooks for: + - Linting + - Testing + - Bump version based on [Conventional Commits](https://www.conventionalcommits.org) and [SemVer](https://semver.org/): + - CHANGELOG generator + - Commits and Tags generator + - GitHub Releases + +### GitHub + +- Actions for: + - Setup Languages and Dependencies +- Workflows running: + - Automatically (Triggered by **Push** or **Pull requests**): + - Secrets Scanning ([TruffleHog Action](https://github.com/trufflesecurity/trufflehog?tab=readme-ov-file#octocat-trufflehog-github-action)) + - Linting + - Testing + - Manually (Using the **Actions tab** on GitHub): + - Upgrade Dependencies + - Automate Release +- Issue Templates **(Defaults)**. + +### Devcontainer + +- Multiple Features already pre-configured: + - Go + - Node + - Docker in Docker +- Extensions and their respective settings to work with: + - Go + - templ + - Cucumber + - Gherkin + - Prettier + - Better Comments + - Todo Tree + - cSpell + +### Docker + +- Dockerfile + - **Multi-stage builds**: + - Development + - Testing + - Build + - Production +- Compose + - Switched by ENVs. + +### Message Broker + +- Routing Key based on [AsyncAPI Topic Definition](https://github.com/fmvilas/topic-definition). + +### Security + +- Form validation at the client using [Fomantic - Form Validation](https://fomantic-ui.com/behaviors/form.html). + - On the server, the validations are performed using the **Value Objects** defined in the **Context**. +- Data **authentication** via **JWT** managed by **Session Cookies**. +- Account confirmation via **Mail** or **Terminal**. +- Password hashing using [Bcrypt](https://pkg.go.dev/golang.org/x/crypto/bcrypt). +- Requests **Rate Limiting**. +- Server log files. + +### Scripts + +- [syncenv](scripts/syncenv/syncenv.go) + - Synchronize all **.env\*** files in the directory using an **.env** model. +- [copydeps](scripts/copydeps/copydeps.go) + - Copies the files required by the browser dependencies from the **node_modules** folder and places them inside the **static** folder on the server. +- [upgrade](scripts/upgrade/upgrade.go) + - Perform the following steps to upgrade the project: + - Upgrade Go, Node and Tools. + - Linting and Testing. + - Commit upgrades. +- [run](deployments/run.sh) + - Display the logs and redirect them to a file whose name depends on the time at which the service was run. + - Used in Production Image. + +## Domain > (Infrastructure | Application) > Presentation + +### Bounded Context (App/Business/Department) > Modules (Troubleshooting) > Layers (Domain, Infrastructure & Application) + +- **Domain (Logic Core)** + - Value Objects (Entities) + - Mother Creators + - Unit Tests + - Messages (Event/Command) + - Mother Creators + - Aggregates (Sets of Entities) + - Aggregate Root (Core Set) + - Mother Creators + - Role Interfaces (Ports) + - Repository + - Broker + - Model Interfaces + - Use Cases + - Handlers/Consumers + - Services (Abstract Logic) + - Errors (Management) +- **Infrastructure (Port Adapters)** + - Persistence + - Repository Mocks + - Implementations (Adapters) + - Integration Tests + - Communication + - Broker Mocks + - Implementations (Adapters) + - Integration Tests +- **Application (Orchestration of Domain Logic)** + - Use Cases + - Implementations + - Commands + - Mother Creators + - Queries/Responses + - Mother Creators + - Handlers/Consumers + - Implementations + - Unit Tests + +### Services > App > (Presentation) + +- **Presentation (Consumers of Bounded Context Modules)** + - Services (Mapping) + - Centralize Imports + - Initializations + - Server + - Templates + - Handlers + - API + - Views + - Routes + - API `/v*` + - Views + - Features (Gherkin) + - Acceptance Tests + +## Workflow + +### Idea + +The system allows users to register a new account, log in and update their data or permanently delete their account, as well as verify it through a link sent to their email. + +### Functionality + +It is a monolith where CRUD operations can be performed from different presentations to the same database, this allows us to manage users from the different presentations available, in addition to having a messaging system that allows to communicate the events occurred, thus avoiding a coupling to the source of the same. + +### Folders + +1. `pkg/context/(modules)` + + - It is the logical core that contains all the necessary functionalities that are agnostic of any **presentation**. + +2. `internal/pkg/service` + + - It is responsible for initializing all **context** functionalities so that they are ready for use, as well as for **“mapping”** certain values to centralize all imports required for **presentations** in a single place. + +3. `internal/app/(presentations)` + + - These **applications** will be used as **presentations** in order to serve the functionalities to an end user. + +### Idiomatic + +- **Domain** + - `errors.New*()`, `errors.BubbleUp()` & `errors.Panic()` + - Only in the `Domain` layer and in the `*_test.go` files can we throw `errors.Panic()`. +- **Infrastructure** + - `New*()`, `Open()` & `Close()` + - `session` + - `errors.New*()` & `errors.BubbleUp()` +- **Application** + - `Run()`, `Handle()` & `On()` + - `errors.New*()` & `errors.BubbleUp()` +- **Presentation** + - **Modules** + - `Start()` & `Stop()` + - `errors.BubbleUp()` + - **Services / Apps** + - `Init()`, `Up()` & `Down()` + - `log.[Wrap]()` + - `errors.New*()` & `errors.BubbleUp()` + - In `Apps` we will handle `Bubble Errors`. +- **Main** + - `log.Fatal()` & `log.[Wrap]()` + - Only `main()` can use `log.Fatal()`. +- **Logs** + - `[embed]` + - We use `[]` to **"embed"** external values such as error messages, fields, etc... inside our messages. +- **ENVs** + - `os.[Getenv/LookupEnv]()` + - Only handle `ENVs` directly in the `Presentation` layer and in the `*_test.go` files. + - At the `Infrastructure` layer, `ENVs` are received via arguments through function parameters. +- **Blocks** + - `const`, `var`, & `type` + - We will group only those that are declared on a single line. + +## First Steps + +### Clone + +#### HTTPS + +```bash +git clone https://github.com/bastean/codexgo.git && cd codexgo +``` + +#### SSH + +```bash +git clone git@github.com:bastean/codexgo.git && cd codexgo +``` + +### Initialize + +#### Dev Container (recommended) + +1. System Requirements + + - [Docker](https://docs.docker.com/get-docker) + + - [Dev Containers](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) + +2. Start VS Code + + ```bash + code . + ``` + +3. Open Command Palette + + - Ctrl+Shift+P + +4. Run + + ```text + Dev Containers: Reopen in Container + ``` + +#### Locally + +1. System Requirements + + - [Go](https://go.dev/doc/install) + - [Node](https://nodejs.org/en/download) + - [Make](https://www.gnu.org/software/make) + - [Docker](https://docs.docker.com/get-docker) + +2. Run + + ```bash + make init + ``` + +### ZIP + +> [!NOTE] +> +> - [System Requirements](#locally) +> - We need to change `` and `` with our own values. + +```bash +curl -sSfLO https://github.com/bastean/codexgo/archive/refs/heads/main.zip \ +&& unzip main.zip \ +&& mv codexgo-main \ +&& rm main.zip \ +&& cd \ +&& make genesis \ +&& git commit -m "feat(genesis): codexgo" \ +&& git branch -M main \ +&& git remote add github https://github.com//.git \ +&& git push -u github main \ +&& git status +``` + +### GitHub Repository + +> [!IMPORTANT] +> These settings are necessary to be able to execute the Actions Workflows. + +#### Settings tab + +##### Actions + +- General + + - Workflow permissions + + - [x] Read and write permissions + +##### Secrets and variables + +- Actions + + - New repository secret + + - `BOT_GPG_PASSPHRASE` + + - `BOT_GPG_PRIVATE_KEY` + + ```bash + gpg --armor --export-secret-key [Pub_Key_ID (*-BOT)] + ``` + +### Run + +#### ENVs + +> [!IMPORTANT] +> Before running it, we must initialize the following environment variable files: +> +> - [.env.example](deployments/.env.example) +> - We will have to create a `.env.(dev|test|prod)` for each runtime environment. +> - In the [.env.example.demo](deployments/.env.example.demo) file, we can see the values that can be used. +> +> In case we only want to run the **Integration** or **Acceptance** tests, in addition to having the `.env.test` file, we must have the following files created: +> +> - [.env.example.test.integration](deployments/.env.example.test.integration) +> - Rename the file to `.env.test.integration`. +> - [.env.example.test.acceptance](deployments/.env.example.test.acceptance) +> - Rename the file to `.env.test.acceptance`. + +#### Development + +```bash +make compose-dev +``` + +#### Tests + +##### Unit + +```bash +make test-unit +``` + +##### Integration + +```bash +make compose-test-integration +``` + +##### Acceptance + +```bash +make compose-test-acceptance +``` + +##### Unit / Integration / Acceptance + +```bash +make compose-tests +``` + +#### Production + +```bash +make compose-prod +``` + +## Tech Stack + +#### Base + +- [Go](https://go.dev) +- [Gin](https://gin-gonic.com) +- [templ](https://templ.guide) + - [Fomantic-UI](https://fomantic-ui.com) +- [RabbitMQ](https://www.rabbitmq.com/tutorials/tutorial-one-go) +- [MongoDB](https://www.mongodb.com/docs/drivers/go) + +#### Please see + +- [go.mod](go.mod) +- [package.json](package.json) + +## Contributing + +- Contributions and Feedback are always welcome! + - [Open a new issue](https://github.com/bastean/codexgo/issues/new/choose) + +## License + +- [MIT](LICENSE) diff --git a/assets/readme/desktop-dashboard.png b/assets/readme/desktop-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..d95966c5c5d7dbb0b54ebd7fd9d45124875ce015 GIT binary patch literal 46982 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

V=bi!8JjMzKxG-(f{#{|HA(NGY7Q6= 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 literal 0 HcmV?d00001 diff --git a/assets/readme/desktop-home.png b/assets/readme/desktop-home.png new file mode 100644 index 0000000000000000000000000000000000000000..4862636cf19a57247c980c2a6f2effa1d4b97b48 GIT binary patch literal 41440 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 literal 0 HcmV?d00001 diff --git a/assets/readme/logo.png b/assets/readme/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..52ba8b9d21f0e60ba34dec197e2a6451c01307a6 GIT binary patch literal 4820 zcmXw-cQl+`*TzS034%l!C3;CDYV;c2FnaGXN|a#qPV@*8g6J}O66MiCM0tc!2O|li z*HNQ~88i4M@3X$&I`>}JK4)M1thLX7cdC)0_HAl5Y5)LmTUSTJ1OOn~B4~3;5`vN} z-f-hUam+gi(E-x?72MwnMA- zgUeVP?tk`GLL?Y3aX3N;dx9YJ8TlKrgmh%herUyZXyw0}|120R)_!=+Zg_=o^q-4x z3!&2P|5JjI(7|qG)nRyrP)11qvlE*CJsMv9PY_}hz0nL|9F~D5hNb{|dU`Id`}glZ z7W*G6DypigU@+K-fFl7X0xt;o{Us(QCN?%RGczlz^e<&)4gaI(FBAWrCe-#UL6V8+HadDl~nWzh$gE#P4(BJ|8L%cIsQn>O6*@+M~Z zWNkL}UF|}}0oDkYx~7=Au5VJ4_)9p9qb9XdbHB2jp^x(XxkdzvGu$I5u5mt1_M9kJ z{e|-iU@cLTzld5HrV`tzE%Sk18tm2ElCfUt z2Sx|7cXs2XvU6Ko7pGJZKr&rZ3XcZ`$E2bwq+!4Ioxe1hwp2Fdn19-Uwf2_otY$d-p)BytTFSkPBRU0p$XWfhKAJmSk}U#ENj>8 znU#qZhSJ;W)L<)*?5#es+7L637JZNr?^Jt$kB}lAO(3t_vj#Ft8?kCBU2d0;v}*ny zOP)76zkk8dWd6NJRHoMz`bOC%C#eyxcc+?auI64S-LI5+{xv1~=+lZl*rIR0h@XMB z-uG+cMOS|^D+r0xf#RhAGq91-{DJETk2}??XMNV4UP6}*uRZ`?b;Zuo`evNcX@x)cmaTJwf&i3g!Z&2mEfFlRG#!m$(rxin?x6m z*5s5M+!-4bjNAL36)kTvNNN=)Bz1JaSuyG*ik>m$5j|3~)O0tjo^T-7VUze5gaTZ! zdu_>tV(iO;xAw}O2_S+Gd82vfk?IfYu~IwzT1r-ti6-D*2UiTVlX-3;3|=FzaZFJB}Q z)@glBL?tcGx}wt_t*lNy)vs@|G!w8Ax6+YDPXRib{T^K^&Aa*3+RAeWhVE`^D4<*>aa0}|Cp9*(Ia{VZ0#7)*r~fi5n(46oCsOs)y-sdx59Io}~ zD+fy0J8QZ}gF(COpH$SKEC;`^gm|~r)e=`r1?8z>FWqk6Q>56;1#u?e%QCu!dH*NL z@=y1NkDSU?XWrYbesmB0Qb8}Y5o-csnyhBxwmYBNfs%nNi+EmN8zQ&lP_ccn-(GTj z05I*Sq-`<@^aEscH?QjZP6i7%zDb8}4~4x3AV7{plR}P1DLJ=s%z8Hb9Dbk8^865I z6-7y9#hIxC=lOa8{(Yw6d9t%pl_X-Z{Lq?aHSK}@czT6V-?OGBA4+3JEi21~w~^>AWFLvo2Yp+hqUMKTRM zG)iHCFmMW;=_8g^HxkxjWr4MUL3>@i-360L^Ccc6)2%_SsJk=UTfY&Ao(34dGnuU$ zs`!{oyde|ilf#ze*+QFDxgxA-Cc~my{kRd-0ST(=RdkVV&?QmOecHe9Vep}-YCr~8 z&Rn*($lx=i*{~a+xqaeHml+a$&yie-41GM8`2F61&bxsoiGcg8z2@GoX+M*eZmT4V zAd@B)7CwyA3{1c2B&%<3)D)pDDK@kBr$UppGt*NGjDXU#BK0PX9~9Z@p9*g@FgieT zH;8js=7ItCO^ERT@Ud?4eJxZH3gL%6#)%6m{lg zF-H6OyX@Hv6JX=`spW02vdCF)&fMn6!=py6Lh$n=Wq!uQi^6U`N;*6LzA zz(U;$H=uk(*tzdLPvBcRq*^cEygm-g%@~0Pj#~hs62ar!0wY`#(=snoCWNu!3tg~+ zT{b%?miI2Ua8(k4mp-isR%nc<6t+n?kH0Jlg6?p8zxcf5NT+zldeKfCus$gv0Z&bJ zsqnNBkwr?WS9(rTM>~36Ds!u?UF(+~qxM9`rF1ZXqssg>@Yu&K>gHc5rhG(xlp2Fd zi;-Tt3&gFER!EvMjyg{9wNwVwd7_;&n==5SVGtwGxQWwX|}-G`Q9rwN%e87|-y}#LDn_ z@Xj!x;L{}F@>4E|ZGL_}6Y=w{{VmU{S1QxDwO8~VO1*~nK!yc;iL{L4@Q2ZF_Ot14 zf0qd|8>4FO96KBqD42%+3FE^pAX)XHZ;y1_4YTo$6TnI3r-SkNWHNKd<~qB3m~=tY zDSjqB6*$HR0G2Qk_xZD$yB~cy7Dv|sm-FFWH!p2!ELc!KGt7+Cs!p2fMQ*90D9eqT zyg2Wuv~f514`seEqoTrgsPisO14z;*;3H{aTO6mqjl0>Cp27sN-dzU+606L9ewH<* zKevc&MGqShW;d>PJ|CGW>fKY(&?vPBGX@q%Rax%qwM6X}8gD;MhVo;h4!+_*-so0& zNk-;>n&u857but%-P$oX9GX{JVk0H#YxLR&uIYVfsKxdw<63kS>LB`sv-)%yQo5H_ zHUQm4lf$OhD;^ubrd4{842ptHNS^0bbR+l_g$<7~7x@^b1rr-xiyJY6DDf(uH0pb|I1ZRIvoa&H^7+%e+gRz%V-!I!IY4^BVYj2L$Beh~I50R}m-7K7tyo zO?G*2LENFu)ACWnv1^3f+gQeelw6DONjsg>EhE;|%oJxlvqZ_u=k8F{9AB-ei#=JX zsH5!aOY8D!NFM~W5nwEm>c`U(YI)MJ;U_}dT(uwgE-ZZbR5W`uxElOvCa<*`wL?S> z?b2<6KNMvCyrVxo7WuZPUrI+_dds>2H|K5&Fc-_u`~>eu|NCWdHm@Bmzb$^0;?r1_ z(d=^c9-nGM+$uz?+|T<>b|TpD+jF@`DN@Q;9Y$NMwA6#5I~Eum#c|Q)utAneN1vcU z?cI-2*9lVeV}AIlleO&+dgN)aGo#tSk#RcMRLzwYerXDYvOX1$T7O*bH_PczNwe+T ztkqGgbokozeDJU|ZwDB|kvP*lq}70~ITHKF@8|qba|V#s!^PENRMxfr!^2xWo>yd8 zGL0t52$9$Cn_wL;B8g}lc--C4VhgO=i1Z%KKOCkkTG;$|sp~-w&_ajzLC%H|4YP5b zUW@tHJ{-_Oj_C`lE#jK}G5X-Svg=)&r)5rD_oA{L=yeaOZR>H+Zz*(k^&`w9ty6>* z<4JVl17VSV#Vc|2{P-PJ)Z?HMs!ZG5HLF*430G{n?Y8l9?OLH~Fa;{}_|Xt}1Se#0 z-s@YTkQlv@TfEkV#1(FlWZ7UV*~10-;y2dO!i^FFlRA~~9qphHIB=nEpe2ujz+zO1 zW7>h+)XyWT%Oxa~#y>PK6Eiv`_?L@KoDUv-_uF3ieE$`1GA$e#7o60CSt_*q=&ruxpE}3SZ2dd-vFUnyrZBRWFXx;nG4}N}M;5|hsQ=@Vt z<)ZT~MLporUV07%({!Hg%FewqMAz8r@RQ1#K-cnDG?bo?AVC8dY(rzt+EBdfhW~{s z5lN<%A=42lk|;+gCB}K^Drk#fl1-`NcL^(xy+`EpOeZ3beoXw^C)2tCj%uH)c=40> z^;pV8q4%C@LklC^b+=I9(^RE-rMtGV@*%ykV6E%nThd-SDhA6DzLcicTk2Ykvn*EE5zSTqKbbhVVLn-dKeBTB(sO;{%EvA zc;v_g4Ua8i>4AHUe>~m`O-iAa8c($<vNw}1{CS5R?pW4C_K8uj1UdXk)@NOXck0# z&O%Mcj{<{FdH5(REQ6(!8BG=fazaultXNiaVJ%^(c)6glO2M{RuIDH5R=PyLrrBrB zU!>khA!7C7F;}vPw9TlK7?|`Ol!juiiNR{HBjflyp_jEdmBZ^j-mc zqFN(PzGnhqw|eV>ltmgDHxt0Uvz%k%EXXYH84Ffmb9V>+Dl#4zUC-_mhfX_ck8(v& z&B{=mdREyqcUe8aWVsv!A>CcqzW)hjK?ZON$Z6|&g!ksEw@32vEpbZHCT1ao$GJ3D z%}Rm1OGQxC1QkYorH^r*iL&Saf=&X}+|hh5#~RjLwBNA8>5=u&huDFlKiY^Iki>Pb zId4cU#XIQ(E(}sGswewJQMU|5Gdpq!Y~8wZSD0kLcrb8r;lmgvD0}uL;|oy|?h@=; zZD42<1%<<}3tvuFPz_iRFNBM`?N$MKkLJ~!oU>=b-qw#ymEc+m-puuRTph>2@&&i7 zoh#7xo5n;=-2=NO3aIA z$Rn_mPZ)Uv#YI(G98fh*dH?{ZaLY=Fse3LTFO1l{S0P0In;85~S5N#ys`%F?_xRT= z&m}X@O7|E?#3p=82l`5^YDc2ssu0(F;nr1%Xgd&ZuL0R;0Z+hR zw6OKf31`x*-eVMO-QN(xd_BbRLtC%0!~PwZX@vcF7P#wY=|y;W8l7oORDAgP$Li(1 zNuE4MrJQ|yuu}yPbVXzJ?aRw3mJ@7N9{KMy)I>7IA_CVg+ERZO5xtFIj$ZDk#<>*gYv;=wqm5oW5F97#ohMsh`ToKK+_%as#*^}azO z)fJ1KOTpq|?Q#idS!UB3S&oOQSSvMN8gyFj^Xd4Gp=ENGp(E@Bb{@QgI#ue2kwn~W zAp;Gbx&r)pD?Gf6>;i_m?!2BO7IeAWZ%2dsw6v3%Kp-hy5pM2Zyvqx8n$ArY*F`Fb)sKe;&k_?P67jIwC%1)2Re);ASF`9~G&+nU!*=!R+nF|3nj!X?-U zzYqOc@yJtt@e_eV5p4qkmG9oo;`$SWOEh4Z>OB8@H|9VB1$q>I@A!I^PT|=YzS|xC-sdXZ;M87N`6Jr}3@t>TKf0MZ|bu zc;*N8=d!C_n}5s*V;5BDVuqgv4N^H+Gx~<2(6Uz!Tz7ZLF_C)w?;zT9a3lOE*EV`lxF!sl$)RMjZ~Vv97jQ_XR(0j#p6w3qLgLVXAt5Yf-oI3DoZwiDDFReibDC z)N_pWLo3%=fIWBCNgUc4b@i<$j8ULdYOmoQbjmzvd)hvCEBv&)oUzn1>GxwSnLYoE zi+$-npF8JQm%p>s=9SgS5K;6*iaQGDo!|`jb~s7qvMKwgBlFN+A-!cGM?9Vf`>Ab8 z4E`7s3h(T+am-n_%dtVnN7wsM5Yzo<4RQW1o$E2|%<7fzttbi(ktS~Z2P-d)GxyPfY3^sC2rt zjg6UeWR;$t=Gt9_5=Tpw&%FZx;u2$}jkNV~SM7Ze2#B2IuO^{?*iPSncenpwx&67J z@Zg3uv^rae;ss!nn8Z$kQnh+P($xPk{NDxhKhMf-OFe94v{kJ;2`dE)BagiV0#E2a z@h;l^zAt3?WN|d_n_#{aO{#^gyDk+F8tyhmaVqb!?U8c(eRY>cT>#qpzr(zUa+Xl} z5rnJl{q2)~59H~dS{6HYQ2@M9lusW6mQDU1NAvl^eP2KMc7tF*w4R7eAr2(a+H?=UYi0Z|=rgAN?`f6xj)sX6;|i>=2Zx_Z1=S9qZid=zt<% zLVIE{;dQPpjTxNVy+qS;Hc94D;O3RN44QNxbdD7)wIp%J%*p?!Z}+!p#6G)Paz$d1 z!J1>v)>g=@@!r#tPI_|8!%LOM!FIA_okG>AHMt3QKZT9Z)o=0DlRbpbQWc6~+*pGntf*mnqwfT` ze?=*T#f0go6cBtG*&?E%7dk!g&NkA0{xdUe^tpl0T^YfXf475Xdkm`Rl1wE5Gk)aW z%t5%lXUoUNZQgaz(s|jEpNTCOji#ZKtX#(;OjnD>>-k55Qj0ZOc=epMCU`C63OqJo z|9kke81X1VAy%Pt%ziX+==jsS>1$QVxuP!Un$bjG;Wsm^GyjHpRCHNCzaz)mZEch4 zii*HD;x9ga|F?sH58@PM75w+j&&^FL07r|DgHR4DT9BB>xi$CE_@Hs^T|tNdQS9K_ z5U3RQ#m9QeG#s|B%d%L@=#WU3#mz41`joxb12Gu<2 zmG1Po)=m5?D+2HEutReM*U*0J-D(IQNyGP z7KWjsAO6BuJkEv)Ucn9{Q>u4tDB}Tf2HJ780)P*}Oc%E;OQfWv#+*kaB(3_2y=##p zgckSwe2^i5@^ZlZW33C1h?B-w(m@JwQiADknA6&XVJ&%tmLKN7tOS(iMNY?+&^MU3 z#j$JXp;_}Zy>`f(>V2&c%}~wN^~E<0*j7SJRAJx7#+;!I`Zs%-y<=|w0>`DrBW@(h zSA_2)k41Lh>&T5vADB=|6;ReiM8kuVky2}bZWL-S%f#Tdd~hrRHk62nh%kk8b@^YP zj0PfzbaizzMZS8QYsTv8%cp694dpwRral6`)n1N}q5QKFKPWXeHw$2Zg*`V(8=9K@ z9k+TZu1}>4REjMq$vtc`L#x*AYDZGg|9LhbYj<+1@7V_m2m})Od-n2pz0+*B_+|Yq z10|hemxi)38>b*6Wnp1qks1IX>e!2im(UZ4%K9omUsFXT?a@NiM@nkY&;k5e!rJC& zxNl3DUfpQpudRlLmscwi%LWytu{GL11O4|9@H9VFdP>>-1m$#L_9r#E86s=1-nK)@ zMI-pKcE!mlXPyPRW;Q_=WmCWJFt6KBb7n;y(`WgKeKxT@XrBlup})hr$m{uj9az2A z#`IIMhDCNhzP|bJ^3cP`A|=$@Edu-g6g_7L%VI6adcHBruJy69qBosLK>epIcX2zp zNm0<@r+lSSwQFmjB^9B<*ch!$nu?ADy#-P?m#Prrq5y7g917rKYXneNcwz19n?_RiXYK=7PO`yJ;UzKRSs z&88OBODDvqtjhT2$eYLe`b7I!+f^^fUad24ok4&e#&ko!LHzIB?>cnVYF|?hdG}OY zo9tJl2iI!fD%N#TovaT(dnQxY3fd`O*H=1EFjY%-OJEYJF+H8r^LS8%Tn%pbuYxaov{y4rEbgMMTO_<1G;BSveymvMDG2jvE~-nTe`m5&)vs=?@I^k>51dMKkuGc(BSFdU za8;ce7>LrXq}*Zw?_$6GRkc?4mi_hrqVSsrettnNj%@;rfb%4pp|vTF@t#H{VS}4H z5?K-=viI==11aKplbe$@Gq+QN+s}R)wyy3`VxZ&^M(9fb4T&A^*3?7$ws2St zontoqPAdS5z(lQT$%zh^o!?CLEPPtjg&$Af&IKPbDfAquAQJ)h#gxAR37S?k+jK--YksRGM=2{dIgU)PHs+ zp66JuUZ!5oNBx;?7#Oe zteqPbB`2`D8A8q@$_Y|OK; zeq+Yt%JHU5wTw(OHjU~drKju!IJYhc1duCSDccDSCYThoMGue z%@H2?S;q`et*elW*K4N%YwPsbJ8X1nDYSveNCl~y1zL6*;YQ97!}FBtjhl#~8SzeT zCs$wLjXYXkP96-TtNuSBU#b9QQ>hsk8L=nFCqMnl@z;RaC#b|^a~rP^PD;D-y^eso%eAaGY=u< z3pKG;=>S1;oUr{H5OpFuFApbL-h)=7W`^pZm;{}cpncH49)Gkj-FX+b|HB28o#v;_ zydFUN=0#@gpxLo{8DJPHN9$61dwiSKel05DSDZo`Ek!XpD(pYa_PURh@TZYGY_Tz% zJ_hwh?@vC<5cRi7F*LWZFM3nhrIA3$H_F9+;M~|ZH^oE41dSf|8L`^Wbm%jUL8h)C zI%x#O;t+<;_a8$Bz|hOP+rLzwdplE7-gI62dr*IuD|`nYsGXWa&-D6@fMVi8QZimb6Nm2AK7k9b-YiB~pJ0(yBd zOEb9-lZAadS1f_{o!|zKxcice6rhD5PT0jd7{MT1B*X?#ejTg?eYySwsu89vVfE)(;a>D$EgXV1`8UwwP|s%8HVQ zI05J>Pu^cKe@=w)*5#PCrTjHgy|piiT@(J)M;HfFG(+Tp9ETSGag^+RG?q$Vmu?Pw zz%PSk%q*_8e&zFRo(Gxdzn+O`Gm|&JWK4T*3*fM6P#R(pCa|m&gn*E|NGz%&TugLm z%YeA;)$&FeeAy#9D11xui79EBD_ zX{14%6ioJ>m3pKE(V&gA$RY9~J)dmHF;}Lr04fn|Ac^rNk!T&twodKwN$bXhqPpQa z=AQCo$8g?BDT1y%`w4TOgGD<%Op4ckpRt`%hG@6;FYdRw{t|qHxP>Rs*&PgD2pTWD zO9bC8k31|2z`mxyR+~edaIw^9B1i$dnY)^H@*+x8u9}EQf1QeM@QkIedOOtZ1~s~qL0Z^wW)_13c=yO6GULPD+$8zq>~DNV&s|pK$>75_#hr?TdVTBE z0cn@WJ~K0Om`thq^hB&Mc&u!$vC+-1BfCQ%82S4mt7*X3#Y9bFwtT?>TiAEi>NMi_ z9MsHjXH3uSp}(`U`5EA+FLB}dpFb2={WzC{AC?x3lee6IC8!r3>s z9ilO}-#X{pUfymoeY63I|A>949gxI{jM;WXerYo~NJ1P|OIU@x7`eIe8JUFghf{!B z^h$Hjq?K}BznnCw_acbGz*#9B{vRRce*~NV#g(bRzNaZxuqHte2%@3U(%`o2;_TdD zXYLL&FgG_hHQmV)@Mr`l2mj1(GOIG|y!x^6(!}~O*uJE#sHiJX%obYX=KIKSa=mF~ z?~CYKQv)&!ervZxj{cY(*z>XBO~@)LhO>){Bt%bFm#$Mdafll6_1`wXpY`#v-F)@`$jXX?5zGOFGM*PtTKoBZ_Vx9(gx7aCV7{H~&Gxw_ zXOW_4YNilz>J<_`Ybh5HEc7p)G3G-R5E3FwzdnSMWJObd>d7natD(@TyuH2kgyJVm znZ*S6M!kFgp62}K```iTi{~ku?y%L{&FR6Cl9CJ_5}Tt#Zi6=}&})j_=+F7Xsddhx zdOHJhF)CB6^NlKq2Fyv#z~mE~c@oPoMcywx@gx-YLB*2lg5gx8Lz zr>7^4iRL%c}@fb)rgo6lE~O*LpWO`i1>eS4KUW(&>Sn`n4Mdk_T+ zx{K+`ARx+iQr~GIW=WKNC@M=bx(MFo72N6{wRnw709Tfk4cB*HKG_cp1ltGP<#)Z6 zwY0VUmNAqRvTQkelKf(0PKoA2~@czDK{nG2t5g^hRRR-PI zK7%n?Io-aUj%Sn+wxn<40LEnw3KJdQ=)?<)ip))q4Gj(BbHe)UEZ^aR<{nDWR|NR~ zLXwgwj#q1KbX9N%&yIk=SZp#k_qXX+TTgMu9DFaaKeb4de5!nFVPZ13_&n6SE-${R zz{;^Kz1Awdu;|v|E(rDf4y`%lO&0}uY+omi-!*-v$J>eR%`6)^y=hbSQqhLbcFh9b zFTx}!x$|-P>XY6;3MY)Zyw|Dhf+3@u>R)X@I&PYW*~0ahNnjxshAraRXE?eJc>6UO zoWoBr7}JS7e5bbSQGe*QpQEuEqUPGZ`uecnARCguF^UENQRi=E1x|z`%8#2G$;JYkk?nd8q%%2@DWu-mvu- z5Xl)gw@&#=RjO_+NFF;rer(hRtK)ao>BE;U+MfXMY5nz9jEPNG}7a}x6b0J+Iuqot@g2^ljt=-y9U;3j#vNA&** z-8ShD7XNztXEF?ZewZ<3M29r8-+y8cAIvYLF{e~KgRI-kS~vO%cegQu1^LeWHp=Q6 z<)_d`G;VX}UPWu?cG0kMbKCxEOEhOsyOx$NR2|}z)_4y1$- zO8B!ICsWMeMShDj`}^raj{KPD=X3dQc+K1KloHkx$({vPhQ2^;Mn94xIbRnGDB)`+AC z_+58R*+NF@{rvnK*0b%o(+j6Bf0>?5PbzB{l97&w#^#7CCY+cv9ULA;00O`c9u6Y2 zSJ17ke-h`9CUb|nm(2$4{wBV@l+OVELp!EUTd>Z~2Wcl#4_DXkzF;SYQ6|XYvNucO zP=}`%I}cCJm^nd8^4^|9utsHqkV}K1;_KwlvmuU9{X> zoNA@}E#B>Lqzsarb~Ni_(`H{!p9l<2WO@Jq%r7vvV__lFAIW~GElVvbo&D*ko=UWZr`|a zwFb@>CVRTO8jo4a1*L%38{r)7qWFDvz2ot@T63MGb*UHuw6(mo%JFtdLOox7p%H$y z{+Q8wb<8&8ULGDiKuAh*vZ0*uT10-B46#<J^il;m0#`rdO${jO4*~ZYn{B^LL3l1H(txS=Uf6W}m3s_avehrOH!d z3K|+3f6hkgD7$8Y((PHJs;%*dn=IY*Wf3`%)e#XI5x$>c*|nr zm@o_=R{SOF%;pdiF(uezOVtuCjbBQNKh(D3ySfC=fMdu-lJH2xin|6tH(rdII|+zQ z4AMeSIFt7iuxyDa)jZ5r_V`r!W*FK!4Q~MTT}DTt9ww@7@i@n{`t#umjHs5hN^^J{ zcV=kh*7amLdtIg52TqN}lAk)k+!dU7ak+&&pBE-wx#$jiwBHQz@wu0cdTSSGpE! zRwEQ$N7Qcxf_i>3tUPYw-jX?D@}>A{_P$Hk!O9wGG5QVc*ddbCOp+=$F%!49B@%FU{nbfV4QUuY14q8 zOVQweM*W$Y9;tpsCVfxub>skoPQ|h}?w_!;yIz@l3jBDo3V_)FQok5u@t>C323KR6 z3fPm6s&i8=PP2~=I}t$t4ymOLo3*YHA}3f|0x6CH>oFppwbMt?D7Xx_!ZVCzTFe_y z976l^oLSN%vb|ZPhEcxwLuJi`3^TeAsV69PBK4hjW(>QY7AEM0p4Y~sAtY_i3PzvI z=pag{ns6!CR5f~3OZM7ZDdz?~@4{;~#1(wDIWBwnFn{&HbW8$XC~n(?j-_^Wl_R{4<5uUL(z|Hq)G61ep=Gn;4 zo4c!dpnY+jG9otiE)87;Ks??&GFY^qhgZ$n1cUzCOfgDncg7CwE76-QWxj5e2Ve4a zdRLnBX*tkz?k<0D3Kd+(xWfL%Gm|BP1 z^k{vX@bZZ%5#G4e`p!YD$ay1Y75}hqGFHaylacqa!%@<<#V;v?v~@uzjnH!YO9NEx z59eHAL1l*(70f5K;6<>}E8R36??E{|Z_|rb-IJ?nazwL!6g4^XGl!243NiRkYlags zf^ET5qbFf>3F(1a8j!u)&#vfuHn)aOAJ^Yu0TkF*xLWW*I_uzLr4Nx4tEXDX&_oViN8ARQCgo!xOx;nRacKITWub}Km4V7n;9CdDuYG2Ej(sJR zniWd?Wj=b03x$~yG}G{7%H`KNROjxjzwNN(I5w4vc2B9lvzz@$`}A-Pql$bW0Y&tU zTB5ja^9mMmpW#s*b{~BDm}Y%V)R|!;=l2ZEMo|U#Ma`BhZ|+YK z6*~Far1RnOBuvpH49#sFyFHSO2)lXDp>3nSJi+mBj=gPuD-4ao=c#T|5w_zTJ;M>l zlXt0t&jScR8T_m-V`VGntlb_h0);#l9FFTAnsceFja|501u2cE6CC8?)2&bv6dd&) z&OA1}Sd&qE3IA(5{C~Pr8>ef1JQNM-O~KyoS5r4PWM5qzoY~(Q;3At#TovE+6*tu}`*g0ys2he!^mofp ztA0afnjbkJpF{_flLb`y$d!)4{F82<6R4*W5G_I6_C2?P3M;;~bR zHJO{yMq~ahRGA0p=9cHjCR7OqZXUp3wTfkBAw6WFsDS|=C@I@g{ZoeDzxMzuKxJId zX7yx@DkAbn$5?as4^H~|x!pKe>NxMIw5962ahhHVPX5m;;#&wZV~ENo`Tq+ z+hZ$S@&ofM4fJe01vSOa^te@X8B#sJT=c7qExvqcc=%XcMy!TRvG2b&H!GgespP5v zRPl6$zvl@Ft!zF~mwHY?dPoM|s*p!c-n`Vd5|~n+HQe(>xq(`3qUz?MprARsx}s@< z0}_s8!Va{2L8b?b%ck)F{(9M!AF1bSD?G2vc?IbeZ+yENFYgw%hv(hLPuxugPrG%i z)U`B?N|wfa{k0N)+>d8}#if`Si^Q*Yz4WJw{NoK4=_)!J7#;oGa3=9?qm_^S+s0Z> z`mpIbgo#U1C1FVY0s{e`o{=C7cDkpwo0ilvz$NIUY3ZRg*nAH9R#ymQ>xo92v48U( zXspbgTt@gBS%ntGl1yDzO;RohrX;|7u*@`N|1K&gC-Yh6vAcg~XjFjXG_5}~b9x~r zX62v$mj4Ivlg84n^LFo4EU%@l!+7!Js;Nm2b|1O=&*<( zYTaxrva=D+Tv%8*BcIN~zt7syLXwG_%2u5Hfhi-eEj*w|-|FJ_$8)XYAxnK(VuMR=82Y8 zt+lBmg%%v?8+3^igM&;NdTVRf$kv>@J7mbRYJV+t+aA^tHhAjle%Mhp;wnFDHf1Sq zQAZ)dWIROz?@+uzMU8d)JzrzI(~TQJOc~!^pH>kfXQn10SIBiSXRI^Ia?m#>$OU)z z|N7O@abIFy4j$-jqBg^Ifoa)E9=mrl-q?IVv(~Cz=W;Q3*aV!sx3OsMeu~HL5@`1+ z7Wu8B!kRHR?Zbn^DIp<`vWy6IJ7nx&TXFo-LzxkQWkxRYs!4+KYu>ck$<{^` zge#}I<1*a)ME3S2gA#O+v9PY&S((wszpJ%%$-nSWlo?_&HlV6gZY;epKaXGNd@M+s zJ?#Hm#c0aBv5}5FEzq*!SRw1+U69>avaMcMQW{6xpx|^3oSR?ZQ0l?OO*_{T z;>ReZD8D+3r|)Jq7R)Hkl?)e$+X6l63MDfR7{M0ax>@N->Z&X|Zf0&j1d@dy6vEyW zFwW45a&QC4aD9FOyYQPXH%DXXVbS4ytr>cr?j&<_@&x>vm8F}Quq9W_(00PXqW*9} zeEl2aQ5l+ENn0B~L@q5UEAHIS}Foj$$zHtho6JrVGGqct$lfYT-B=hx|N zYo|~yjh;uT48DuSV^Gt$oa3E4YE;S*(hBdq462W_9^&szpSHA?>yH^%f$3TwPtk;qd$A<>~YD(im*awX8H9 z9Rt6tiK9=`=E*YD!gjX4D@(PLw!mvI7mhUf@v*T7dfYBsJ1dQ^;O^pL3k#3yp?lvO z`2onOkB?Dv^PHlAK~`GUglWUr{(cD_x>&AO-BJY#ARuq+tB}!>{#pE}oE%endOH8w zl9k9(dwULdIUr`c`>mXer=2GzDt8H+jd_5W1pT*XW=?FTU2bdxAl%efc6lEf3e9X| zQix7TUC!3mMykvfVCxS;*_S_*k`vgMqNsKevNM^&cH<{JdzU+2Kl;D?Z61uJqoqxH zx3Q=kQQD~5thJ@N{2QXqS{*q_W7Er_Tu~0i2wl=8rW#h+I@VM%2robZR@-nh7}YPmdb3&5#8j`{Ayg> z+~mT3j6?n)2nyi0u37iS(-*La9t3MLnhk3=?lva_zq;p^vzWC6(L=>DE3L41oww)Q6Ehb1SF;SJ$?0Kn6%TkuYU!S3V)=?fToRTuO{ z*+KMJ4bn5Z;qc>3u%q&H=ZQh#v4}6Vm9_P98nuW>cV#6qJ+{eJuCJ%1rK0k++Ou>0 z@X%V%EOyWZw(3=wcEnU}lQ22}UtML%sa{FjIbI^>K=#l6EN5V5UR~;>2(OUS)qdfR zSQAIqKYldAEjfvwZhJnGNi4GDl92AZ1quY)c2 zc9ClE=rgW)wKLm*L`gC`Gh_2;YpDPF<$v(*Z?}q`Rx_#2TsI>ts{>Un0|4NtIuegZ zR-T(HO4m@=M*Ghn8`YAZw+h$SacI(fEEE+L+x4r?&(B#=7Z6B~C8TkSLij1a8~i~;1bj4(vsDQF3I9~+=I$1~ky>K|1?D)|-b=~KmZm*Dj4P^L z|5ZiiH9wHF2icvMHsE-BXORRXCAT57_|%OJ4RUQ>E^-VWuyvPple6#Bws|MIUYE!ugEizKIEX*Qbl-H%+=+k+~E-gn_ZIzkdg7+dqYKzvngH$3b)j^LVXk~ z9;PrNO4w0fb?8FA!&>R=>;jtp{kvqzkz0e?XEx#8(2DuWZRLQ}o`w0GjeBLR=2BJa ziJ-gI>U#JL`D23X*`Ib{qvrqM-G6rluE)Ummv<}rSRI{P_Wv(19U`k!ewaV0V8p-R zz6(mVPwW2?&zp`cf!EOFW4P1JY}r1Z4^F@@Zu(?rM>0zBNA|B&;M>$V6XOe+uDlr( z9SFiXeq^yG_c)(KT5DA2#lmUgRAzno`!&yN%R2gjjPcEjX5=Wy-nszQumMjtp%{LT z;Bc~I@CtV`j*+C$dcs%aX!IYJbu0J_T4^9K)3&@36r7E&jeomgt3s?c?#TV5<+IQ- zDB%9vDyEfmJ^{HysV>-Z`#kt(BkM3x=V8KE$0OIAM}G>5va%NRvR)azZ86nGs;&ZE zad9^gc>ZJI$Sg@LX-C_jNayVZvq7Z4$Kli^@0iZ{YrVo)TNHq(Tgfnny2f8tXE5jE_O9TWMM7j%3I`HDfkxVDzKz`tU$17j%jm?aFo+oYR*NB~&g_3=^ro~)`Q^^_9mz8oN3G4lPX(e&U zj2g(v&>`)}$bI5Un);_{K4d5;%iK@gdk3b>pYcw_}F$ATdJj<=_74U(K%( zp8fV;Z^wQIi#%+nLFJ_F)&|q;@J;?zF_Q;qguJ9T%DR5D$7u91t@{cZU zmX#5Y6TLcWEUP-2>5g2{JMA1H=PK1442ip4l2O_-a$EOhDDxG5Gxl^VsxIjp_bB@| zoB5MZvwmx;%>95napFfh>im$Hjvf= zF^jAts*Wz_t-mBAo5fYJ#oFjI8YiB%90~cAs)sc+WCKD236DGl4^`8NEH+Ol=RV{|p&N!X6iHY(N&q&IOg}sd_P{WuYO?}nT!PkP`d%-nN2?$oa)$$=i*s!DGBF^~x zkiyI_z32*;psc_QD5DY$ITNDIMnE@2xn%DjRq8Ojdk|Kl5kR+@L$+w84n|YH-oD{h z=lsn7BUdK=oA@h5vHTCXTJf}-^e-6Ren1gR!c|7ZV58OPy>f+0e#jJ7g^~QaRTiAi zQ{naPT0k6+k1amsG_~$OAQsvKqwiKwqcIXyBCS?%>Xn){lzvzBYsmGVTLT?Q5mL=@1}&u2$zkvL z>&{cam4p;Q(`=(v%ZheOv3Kc>SEv~tJufr;73Xn_W~}5&JzSXmNumAw%Wm{n$UAtD?L~jWNmxC7J29DHQWw$Aan&m#Q zLO#Pf&AwsTx%8%bwo^sol>7SZtX^egr0s3LTs!|{%LS5Brr6=TWxX7vLHnsF!(fN& z;M_#y{<^ivik7oG%`q(qJdUe!eRY-Ij(IC}sh5#!d?PdA7iEDj#mZFOkx4{8saNo$HAHnPR9*UF!>dA15l5>U)F9 z{7Zio9USIE+dpQw$qQt00=8a!g{D{Yj5*|UiWTGP`Ys3?_@%X9H5Zb!s>!wu@`EZy zzTET`HNU%vZ&Xt*f&8c6y7K*1ymUPljzoEEnXYc2W?(`nCWME=PtSs}>O$Z60kBLa zh%Bg@7~FQ{Dd0k6Nx2?|QfAcz5a<@R1RJWRo4l zzr0ML`siACW;>|YN+%YtZLVy5=qdRZQl84Hftfn8>hm9Ev(ytgd{)s7)^1!iXJ8W0 z4ud7;s$^DH#0uoXQ?m$~o*qUwDeK}+jn@bVwyimpyF9aTbVcp>Ny>4KM3OoG(c zXS4cRXNDJ954mwaKt@H#PLfJJ?YbdDb(h3Q$~QH{Fpm$JYj#^h=0?t>=I@rHxhA#` zo3(Tr_vd*!Nic0#MUogF(@<2ShhHV7hzMpP28C~9pR0qw+XI!fv@8G8z)Z&|)MyOs z&IRMkVSfwUvE2)M`7^^+Fe|>>Iy!U_DTxe!p2gx$mi4EzV$b7NkNXM^G#u?K)cW2h zLL6M@2}cqB-I?$)5Pbd9vkM4G^X0hSWGK=Sd?{u)xhdE1d!^eMn&-Mlv3De}_yhft zE>ZUMV8Xoq6-+#4IPl!R=V$fT{l&7)!r*s`S3V80T4m)356lWUS&hp4x`)U<)&pdV z?*$X+Pe!I@A40^mc;^*flKIQ#$Q)OlG zivL5~PlGTC=z8&Io30>=HxGXPmhb$(Y!M_rY)7ie=>}G_)|WM8vI@Obmcptc(Tdk3 z5=bR{nAbG%jVs$Y74)qL*T2y?5>Uw%It_p6*MS@|Jw?F84mb57lj?%Bs-y0&Df z*n;^(Lz=3p0MiBYhCYeIK5(aGRp9U5Xf;C;&QM#!{u(PSB2Ai#qGPcNptCnL@BkFD z@jSV|Ytl4c;Ip-S zX4=8#U{?G{F?QftrucdxRwj>}4C!`-Dm zRk7Io(~^;Bxv_KY_L92O91O~Tv9;N%qJ+^f(=smmHUX(^=>&^cI-7NEjttmbWD{jr z_h%){a^5sK9XFkm_r~XAp|R1}j)4^2Z&Qz|*_ftttjL@C18;i{_%x7AvW$7=^1xJe zgfmL~S#MipjpJAnS|7+qpu&3O?eCnR+E!s)w-l@xOXBRcba|Jdb##1F*f^ueTHeI( zf8ZsDw5I{{R%11Xy3n9#;pPJd%WA7}^T(SJiLuqFUMXP!RhEaY~ujU9Nj^uAy?!pn3no zs;&HJ2`Sh!FFeYXU^YkaF|(JImdTx8M8*Y~B1nU1fd_piH~j&+bT z1C$l~_@SNu>M#<@uF5uRgBy40{lFTGRu4Oz0dS(j$Aq)Q*{b#-uM*S0Jy!FfKWznv zh-6IQwJt>IUrb|CYAM=3N?h6#Ydcc5DS~Bec8zfpD?{Y%ASq8d)TgB5 zkW7rI$g=%IyY@Sz#8qwshIAYXbI=6hkfH&6K`Vh+{QqMRB{K4R7@O$6_rBkmnCQN#`ug;3x^UXQsb8JBzd+~NRjo@jF+!R!d7EPO!4IicH zFvJv153d#m26{^)6CdEFX03lX1DMP$u^ks=qIeD-E8P(pSYuJ7!o zBx^kj49IL-gAJ7y2WeFwENL?X$1w8G!>_I?PtGq0W{{-=pvc-Byt7V^o|!1b?#U@6 z#GWYR0kkTi8fG&kwuIbdBW`zOL|*jUTU#rd z<#0!Jd|(R5dw#zApd26nV#{%nnQhF;&@)* zg>7O#_VhSg*?kQRdd(7 zd)1?()WtV6PT=rp+pFd1jApsm zoa5u;vVY~f{+ZbSOCV6fm8|Aj_g$>Se--=>j;)0*GBO8yyTMy`Veon9^&hC5uYB=L z=i>*6T=3IsZ!f%HJCRpOUOp;1nu{1?WMl#r{JBxns9e1_r?$26;c5-Ro8vbbnguIR zWyo~KEAdb$RFZDd!f!+qDZ-vo_@gc&ymy<%EliAUP1WTS@UgAVB~twN9qqR_L}d^X|Go~TwvdC zQ|W4kop&@_y?eJDJ+29ADfFV))ho{jb~PcIODFDHx*uwF_>3V-j2y4~kl!G&P2fdq zXx2sckEq(6V4m&VfjtQqjLhqayiHwQz05R`HAew172i*oS^q378ZJtSoK26xas6Qerz`u zny)YgIWum=^PoH_z(TC2gTWfe8matlb{Owpt}0QoyZUvSI6MJ_I61Qv)!54he-4)j zGkPQs%5R13^AN{z+Y5i}y1LXi*!a+8io&F=-Mtap8Y-TL7#M{*4=s>(561msq_X=_ zws1rhFCz>Vj+Y-Ms2OFIXc$(v98x1Lk4l;hAMJl}&QMTv!-#aM^3G)G=+w$>jwUI? zifV^Lr3X*b(@C)h5xeHc=@Ne&ZZm=z|Bqg-GpeaA3;R^S2KrDziXcccAfSSD>AgLA zF@zd=?^Q$?K#`(|2odrCsi6p=8WLavMgk!OLk$q5N(&MQ5EPh*Z>^a>^Va;Dv+l36 z?%L<>bJp7T?7hG5qZXAi<=sTqZ*HzaNOGXMcj5Ub&*BX3+vi!m?l;^+zwpcJ@0Uov zk=kns;5#zmwsS_0{5%WBV??v&()~e8H-4*iRhTrfZ`M9J$^7bZQ?OYO_UJBB15EGU6*2`^UwTKzFpvD<1$mCY-Kt2Dc`33Q!PP_n66LS zE->1SGp8@>6Cuwy8~Mci?pUW5du`&?4^FJuY(0fMPtQi#-A|HP-Z+~wzD^1Ca4#SC zAV=)AbkM@3zPbd&LklQp3&TDg=8&q^py!JKoX@neCJL#Iy82PV8nyv4Vx16c@jN4Q zwIq3AC?0{9G%;yNIcNsx;s?T-=fa$RWXOj0eGPF$t`UJ07Pi7Stxlm%uad7-`9c>g z+bktFh&%~sSeGYtc-#)#sse6Bz5li~y20pL!5UP%CocdKRqWPIuO(jOZ}Cyuv{cy9 zN_&9SL45Fmmm2|cW>Z$fOEnk)rIQt{JEjErk-AwW{ELG>8(D&Ns%VG_4*NE5ES+6$ z<#_7E-Ms$A#gN7X7Q2p@pk_@i$znoKpkrmQVu47tjU?F~gwoB*Qu!F7I?835;}A-j z`hLo-ffU}(_I#>d^c~j5-CaI1R@o!;PeN8I!-1alF6Zv0)pU16h#p_JnH86$v2ju5 z!-rC--t13VE$+F%8t&NnTKTsq0X3DaGE@k~nGJ+m%Ea2OQ|-j_4|Uxj#u_8-EY1TQ z=X%tR#RF0=TYzV}a@FpLOQ$3!XPu*J>qCS@^ITJlepg)7(|F>kw)gG8$u;qm*ix{< zA&g^S62?xx->c|PL5a}mM8`8D^r)h0x?8sQcY_><6YG?rm!vsxcHzN~1z4Ym@G3;Y zdWHYG3RdrqjoAnv+5zkKhmQ@zA&q?slC$Jn(6I^8Fh z$%~$>1%}&EQVbR{rV`93mo#(I;Xj(NLep?&foz2cAuE)!iZT652}aIP_|RWM(q$l4 zdnSPx#-_UYByrGF%Id!R+aheNfgc%lbd5{F?|Ff$+L7N!h^Lv(xPLATS9q5#|D#_0 zpdxTVJtLxNAMlr$!nWuq=HRQT>MLr%TEZkNk}XS(qvhtKR`89#XfUVxRwlU1v`(;s zx%v3mx^INdV6iLVH9D3fdH2rOjE-)w{1={^ws=Cb)&<(=>6k+-P2TI>>~iy9*za8?qb{zXXPd(Q2le$9=KImVjOkuz(+$QN#HX+%{2Q zBEv1~AA`XR&4nXy$y$N};!qh}D~%q@&;goW*RAtt&P(Z|g-B=NEki(l{@kq8`d?RD zfue}epv~27;+Mb*g_lVdm9O$_gxOOx1Z0=Igap0dq;>leDx%B>yWm-4%j3q_WRX|?=^mhDIiK4Fch!+q@829oO9ddf=`<|!&C2`S z>Dp#?f)wah$lS|YjczmGV(L8AeE%pz$2?Osd&$SgJEN_BYFUrLA1!4d3On!v?VviM z7I-E<4iTX*c5Y7ok*;nLBK5=gP*?;(`}*5%b+L*bvn2axpw6!9q$elKtCIy!6@3Dk z1ca!AHO+|R&le?uRiyI+ajLxYg>#9cG)xHJPxqnoTTx6s46wujfR_!{f6et^W`9wK zsmp1QKgXfh&7A4OvWkK%ZHZ~kR$|1)M&Zgil?N&`K0apO@8uQMrdQihNQNH6LAs|* zm1gnXpB6i*3_!(nYF+%9DCBT3^z(8fw#>s_f}d&A8b9YO0NdhKAOi@NW^J_ zcgtGt=%nNsEs`oE>bunan%JKvHUGL(b_Vcb?11))9j)?f;ky^v`p4~dzgD2$XBm`M zUrgrJz3mAeoy)#_dl)~u`s`0of*%Ryd3+yfZM zFOc2Y(d{*fT+OmlCov&kW*u-<5foih9gG}`qK#oWnckl>(VR(42yZhUx zPYiH&bF_9FF#NpCT?Yw{sijEe+T~ReLTUIdw*_oi;@D+Xn;PpJcDw2P0to!)#NUo@ z1GUH_nW&y1-lHpGxuI&%n#5Ova}8P=b0a7HYF@EU@{-=)gN#1+E-TH^3)lt(l@tpW zOCqET#vKvxw@KF)chX)|v^#ng#^QHlp@mRYg^Pc)-eWY_MbK94bvWMxj^o$fyR)DD zby738iBnSrCLRVpIorWy)3(t3{MXxs_y||omi#`5$9=>Qi6q{;6Vj$pYA;tu^iD@s zFtAtsfg&+ezBnAtkei?X$g70D8h{{pt`$%y3r5Yh_B_hLS}*71#l_`nL57@ZJ{QCJ zN+lg%Y|m;QCvfsk37s=g{NY_wgs+#^=Jx|lP0cc|CosQ#7UupTnUoY=BWLEFDZoY6 zIH&!Lxv|5kn1|&k+xN5=$?a%l`1mwIpf}V6YBDkKkF?yC^f3LJ znws5~h@n0%3%&idEejC&&3{t#u4i8oK>Zm@9+tvTk{ah$J3xYG= zg7T+mEOK68j){&ILhk)>{M~Gc{IwvS>pbu#(z@gogR+~yX3G;2I_IGA^}Bc-M@RAi zT31Bj?*e*cT#pN86l;Y%3mA?TV!wK9q)rjQX$VFp4Fgeib&hqQHgjRXaX!x`2(YP= z&FvHR3JeS^Y2!Ng4`Bvi0Ah%C-6^Kdx=?3JH`di8 z9pB{X>nTQuGDuE_D;pbfXhw!S^zBn>WgKc3yz(V}*i_gXbW1S%06f*Hr)^E&i>Rf^KwXJQp zI0@=l2eDj`8oGw5`_G)J_z&bkJ?Ykp^XRR2XvpW!yP*g35tOAi!kB}dLtpuB7A=%I zJ4B5IJ39y6;^9lrbSw|v5DwaG%O1J?Xw(}z(BD6edK?!R89V8{Ycf7L@j%&|fpP)I zQD~4YQ_jlm7cW>8V2tg4d}O-NpPp-Dy_Ka;ou7x#8rV1HV$o={_V1PC`XtKW;2_S@ zqy!Y+p^6uxCld$+->=5WEG#TXfE)-8IouS{Vi6UCu&(jH8gCAhW5+8g(SFts4sl~+ zXkgy-*jV*2_jeZEQKY@3s`2d>(*bu!T&Xf6IA&u4mc(&W$o}9}+9E?$uJvU;ZcHIg zQCfPCOos9hJoxeV@~10@MMd~L&_rVBl8>B}Y0Q#F*nmN>4IoW_fm5p7pwv7V`F$O; zuOqu&kaRfI)(>6-#hBvz%d$wK<*Td1z$@`b&Z_GLb?ozb3Zm4lch($ literal 0 HcmV?d00001 diff --git a/assets/readme/mobile-dashboard.png b/assets/readme/mobile-dashboard.png new file mode 100644 index 0000000000000000000000000000000000000000..7cf862c3b2e7ca8f4a4c2b95f105fcd412fbfdb9 GIT binary patch literal 36906 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 literal 0 HcmV?d00001 diff --git a/assets/social-preview/social-preview.png b/assets/social-preview/social-preview.png new file mode 100644 index 0000000000000000000000000000000000000000..0d5f38dc3e72f70770d89a4093650aecec25893b GIT binary patch literal 9688 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 literal 0 HcmV?d00001 diff --git a/cmd/codexgo/codex.go b/cmd/codexgo/codex.go new file mode 100644 index 0000000..e8a7a5d --- /dev/null +++ b/cmd/codexgo/codex.go @@ -0,0 +1,81 @@ +package main + +import ( + "context" + "os" + "os/signal" + "syscall" + "time" + + "github.com/bastean/codexgo/v4/internal/app/cli" + "github.com/bastean/codexgo/v4/internal/app/server" + "github.com/bastean/codexgo/v4/internal/pkg/service" + "github.com/bastean/codexgo/v4/internal/pkg/service/logger/log" +) + +var ( + err error +) + +var ( + Services = "Services" + Apps = "Apps" +) + +func main() { + if err = cli.Up(); err != nil { + log.Fatal(err.Error()) + } + + log.Logo() + + log.Starting(Services) + + if err = service.Up(); err != nil { + log.Fatal(err.Error()) + } + + log.Started(Services) + + log.Starting(Apps) + + go func() { + if err := server.Up(); err != nil { + log.Fatal(err.Error()) + } + }() + + log.Started(Apps) + + log.Info("Press Ctrl+C to exit") + + shutdown := make(chan os.Signal, 1) + + signal.Notify(shutdown, os.Interrupt, syscall.SIGINT, syscall.SIGTERM) + + <-shutdown + + ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) + + defer cancel() + + log.Stopping(Apps) + + if err = server.Down(ctx); err != nil { + log.Error(err.Error()) + } + + log.Stopped(Apps) + + log.Stopping(Services) + + if err = service.Down(ctx); err != nil { + log.Error(err.Error()) + } + + log.Stopped(Services) + + <-ctx.Done() + + log.Info("Exiting...") +} diff --git a/deployments/.env.demo b/deployments/.env.demo new file mode 100644 index 0000000..c2486d1 --- /dev/null +++ b/deployments/.env.demo @@ -0,0 +1,45 @@ +CODEXGO_BROKER_RABBITMQ_CONTAINER_NAME=codexgo-broker-rabbitmq-demo +CODEXGO_BROKER_RABBITMQ_CONTAINER_RESTART=on-failure + +CODEXGO_BROKER_RABBITMQ_AMQP_PORT=5672 +CODEXGO_BROKER_RABBITMQ_ADMIN_PORT=15672 +CODEXGO_BROKER_RABBITMQ_ADMIN_USERNAME=codexgo-demo +CODEXGO_BROKER_RABBITMQ_ADMIN_PASSWORD=codexgo-demo + +CODEXGO_DATABASE_MONGODB_CONTAINER_NAME=codexgo-database-mongodb-demo +CODEXGO_DATABASE_MONGODB_CONTAINER_VOLUME=codexgo-database-mongodb-demo +CODEXGO_DATABASE_MONGODB_CONTAINER_RESTART=on-failure + +CODEXGO_DATABASE_MONGODB_PORT=27017 +CODEXGO_DATABASE_MONGODB_ROOT_USERNAME=codexgo-demo +CODEXGO_DATABASE_MONGODB_ROOT_PASSWORD=codexgo-demo + +CODEXGO_CONTAINER_IMAGE_TAG=codexgo-demo +CODEXGO_CONTAINER_IMAGE_BUILD_TARGET=prod +CODEXGO_CONTAINER_NAME=codexgo-demo +CODEXGO_CONTAINER_VOLUME=codexgo-logs:/app/logs +CODEXGO_CONTAINER_START=./run +CODEXGO_CONTAINER_RESTART=on-failure + +CODEXGO_BROKER_RABBITMQ_URI= +CODEXGO_BROKER_RABBITMQ_NAME=codexgo-demo + +CODEXGO_DATABASE_MONGODB_URI= +CODEXGO_DATABASE_MONGODB_NAME=codexgo-demo + +CODEXGO_SMTP_HOST= +CODEXGO_SMTP_PORT= +CODEXGO_SMTP_USERNAME= +CODEXGO_SMTP_PASSWORD= + +CODEXGO_JWT_SECRET_KEY=codexgo-demo + +CODEXGO_SERVER_GIN_HOSTNAME=localhost +CODEXGO_SERVER_GIN_PORT=8080 +CODEXGO_SERVER_GIN_URL=http://localhost:8080 +CODEXGO_SERVER_GIN_MODE=release +CODEXGO_SERVER_GIN_ALLOWED_HOSTS=localhost:8080 +CODEXGO_SERVER_GIN_COOKIE_SECRET_KEY=codexgo-demo +CODEXGO_SERVER_GIN_COOKIE_SESSION_NAME=codexgo-demo + +CODEXGO_DEV_AIR_PROXY_PORT=8080 diff --git a/deployments/.env.example b/deployments/.env.example new file mode 100644 index 0000000..c1d7c2b --- /dev/null +++ b/deployments/.env.example @@ -0,0 +1,45 @@ +CODEXGO_BROKER_RABBITMQ_CONTAINER_NAME= +CODEXGO_BROKER_RABBITMQ_CONTAINER_RESTART= + +CODEXGO_BROKER_RABBITMQ_AMQP_PORT= +CODEXGO_BROKER_RABBITMQ_ADMIN_PORT= +CODEXGO_BROKER_RABBITMQ_ADMIN_USERNAME= +CODEXGO_BROKER_RABBITMQ_ADMIN_PASSWORD= + +CODEXGO_DATABASE_MONGODB_CONTAINER_NAME= +CODEXGO_DATABASE_MONGODB_CONTAINER_VOLUME= +CODEXGO_DATABASE_MONGODB_CONTAINER_RESTART= + +CODEXGO_DATABASE_MONGODB_PORT= +CODEXGO_DATABASE_MONGODB_ROOT_USERNAME= +CODEXGO_DATABASE_MONGODB_ROOT_PASSWORD= + +CODEXGO_CONTAINER_IMAGE_TAG= +CODEXGO_CONTAINER_IMAGE_BUILD_TARGET= +CODEXGO_CONTAINER_NAME= +CODEXGO_CONTAINER_VOLUME= +CODEXGO_CONTAINER_START= +CODEXGO_CONTAINER_RESTART= + +CODEXGO_BROKER_RABBITMQ_URI= +CODEXGO_BROKER_RABBITMQ_NAME= + +CODEXGO_DATABASE_MONGODB_URI= +CODEXGO_DATABASE_MONGODB_NAME= + +CODEXGO_SMTP_HOST= +CODEXGO_SMTP_PORT= +CODEXGO_SMTP_USERNAME= +CODEXGO_SMTP_PASSWORD= + +CODEXGO_JWT_SECRET_KEY= + +CODEXGO_SERVER_GIN_HOSTNAME= +CODEXGO_SERVER_GIN_PORT= +CODEXGO_SERVER_GIN_URL= +CODEXGO_SERVER_GIN_MODE= +CODEXGO_SERVER_GIN_ALLOWED_HOSTS= +CODEXGO_SERVER_GIN_COOKIE_SECRET_KEY= +CODEXGO_SERVER_GIN_COOKIE_SESSION_NAME= + +CODEXGO_DEV_AIR_PROXY_PORT= diff --git a/deployments/.env.example.cli b/deployments/.env.example.cli new file mode 100644 index 0000000..458c3d5 --- /dev/null +++ b/deployments/.env.example.cli @@ -0,0 +1,20 @@ +CODEXGO_BROKER_RABBITMQ_URI='amqp://:@:' +CODEXGO_BROKER_RABBITMQ_NAME=codexgo-(dev|test|prod|demo) + +CODEXGO_DATABASE_MONGODB_URI='mongodb://:@:' +CODEXGO_DATABASE_MONGODB_NAME=codexgo-(dev|test|prod|demo) + +CODEXGO_SMTP_HOST=smtp.example.com +CODEXGO_SMTP_PORT=(25|465|587|2525) +CODEXGO_SMTP_USERNAME=codexgo-(dev|test|prod|demo) +CODEXGO_SMTP_PASSWORD=codexgo-(dev|test|prod|demo) + +CODEXGO_JWT_SECRET_KEY=codexgo-(dev|test|prod|demo) + +CODEXGO_SERVER_GIN_HOSTNAME=localhost +CODEXGO_SERVER_GIN_PORT=8080 +CODEXGO_SERVER_GIN_URL=http://localhost:8080 +CODEXGO_SERVER_GIN_MODE=(debug|test|release) +CODEXGO_SERVER_GIN_ALLOWED_HOSTS=localhost:8080 +CODEXGO_SERVER_GIN_COOKIE_SECRET_KEY=codexgo-(dev|test|prod|demo) +CODEXGO_SERVER_GIN_COOKIE_SESSION_NAME=codexgo-(dev|test|prod|demo) diff --git a/deployments/.env.example.demo b/deployments/.env.example.demo new file mode 100644 index 0000000..5fe4a91 --- /dev/null +++ b/deployments/.env.example.demo @@ -0,0 +1,45 @@ +CODEXGO_BROKER_RABBITMQ_CONTAINER_NAME=codexgo-broker-rabbitmq-(dev|test|prod|demo) +CODEXGO_BROKER_RABBITMQ_CONTAINER_RESTART=(on-failure|always) + +CODEXGO_BROKER_RABBITMQ_AMQP_PORT=5672 +CODEXGO_BROKER_RABBITMQ_ADMIN_PORT=15672 +CODEXGO_BROKER_RABBITMQ_ADMIN_USERNAME=codexgo-(dev|test|prod|demo) +CODEXGO_BROKER_RABBITMQ_ADMIN_PASSWORD=codexgo-(dev|test|prod|demo) + +CODEXGO_DATABASE_MONGODB_CONTAINER_NAME=codexgo-database-mongodb-(dev|test|prod|demo) +CODEXGO_DATABASE_MONGODB_CONTAINER_VOLUME=codexgo-database-mongodb-(dev|test|prod|demo) +CODEXGO_DATABASE_MONGODB_CONTAINER_RESTART=(on-failure|always) + +CODEXGO_DATABASE_MONGODB_PORT=27017 +CODEXGO_DATABASE_MONGODB_ROOT_USERNAME=codexgo-(dev|test|prod|demo) +CODEXGO_DATABASE_MONGODB_ROOT_PASSWORD=codexgo-(dev|test|prod|demo) + +CODEXGO_CONTAINER_IMAGE_TAG=codexgo-(dev|test|prod|demo) +CODEXGO_CONTAINER_IMAGE_BUILD_TARGET=(dev|test|prod) +CODEXGO_CONTAINER_NAME=codexgo-(dev|test|prod|demo) +CODEXGO_CONTAINER_VOLUME=(..:/app|codexgo-logs:/app/logs) +CODEXGO_CONTAINER_START=(air|'make tests'|./codexgo|./run) +CODEXGO_CONTAINER_RESTART=(on-failure|always) + +CODEXGO_BROKER_RABBITMQ_URI='amqp://:@:' +CODEXGO_BROKER_RABBITMQ_NAME=codexgo-(dev|test|prod|demo) + +CODEXGO_DATABASE_MONGODB_URI='mongodb://:@:' +CODEXGO_DATABASE_MONGODB_NAME=codexgo-(dev|test|prod|demo) + +CODEXGO_SMTP_HOST=smtp.example.com +CODEXGO_SMTP_PORT=(25|465|587|2525) +CODEXGO_SMTP_USERNAME=codexgo-(dev|test|prod|demo) +CODEXGO_SMTP_PASSWORD=codexgo-(dev|test|prod|demo) + +CODEXGO_JWT_SECRET_KEY=codexgo-(dev|test|prod|demo) + +CODEXGO_SERVER_GIN_HOSTNAME=localhost +CODEXGO_SERVER_GIN_PORT=8080 +CODEXGO_SERVER_GIN_URL=http://localhost:8080 +CODEXGO_SERVER_GIN_MODE=(debug|test|release) +CODEXGO_SERVER_GIN_ALLOWED_HOSTS=localhost:8080 +CODEXGO_SERVER_GIN_COOKIE_SECRET_KEY=codexgo-(dev|test|prod|demo) +CODEXGO_SERVER_GIN_COOKIE_SESSION_NAME=codexgo-(dev|test|prod|demo) + +CODEXGO_DEV_AIR_PROXY_PORT=(8090|8080) diff --git a/deployments/.env.example.test.acceptance b/deployments/.env.example.test.acceptance new file mode 100644 index 0000000..bf15584 --- /dev/null +++ b/deployments/.env.example.test.acceptance @@ -0,0 +1 @@ +CODEXGO_CONTAINER_START='make test-acceptance' diff --git a/deployments/.env.example.test.integration b/deployments/.env.example.test.integration new file mode 100644 index 0000000..c305e62 --- /dev/null +++ b/deployments/.env.example.test.integration @@ -0,0 +1 @@ +CODEXGO_CONTAINER_START='make test-integration' diff --git a/deployments/Dockerfile b/deployments/Dockerfile new file mode 100644 index 0000000..c0d0d5f --- /dev/null +++ b/deployments/Dockerfile @@ -0,0 +1,33 @@ +# syntax=docker/dockerfile:1 + +FROM golang:1.23-bookworm AS dev + +WORKDIR /app + +RUN apt update \ + && apt upgrade -y \ + && apt install -y sudo nodejs npm + +COPY Makefile . + +RUN make install-tools-dev + +FROM dev AS test + +RUN make install-tools-test + +FROM dev AS build + +COPY . . + +RUN make build + +FROM golang:1.23-bookworm AS prod + +WORKDIR /app + +COPY --from=build app/deployments/run.sh run + +RUN chmod +x run + +COPY --from=build app/build/codexgo . diff --git a/deployments/docker-compose.yml b/deployments/docker-compose.yml new file mode 100644 index 0000000..65b4ccf --- /dev/null +++ b/deployments/docker-compose.yml @@ -0,0 +1,86 @@ +services: + broker-rabbitmq: + container_name: ${CODEXGO_BROKER_RABBITMQ_CONTAINER_NAME} + image: rabbitmq:3-management + environment: + RABBITMQ_DEFAULT_USER: ${CODEXGO_BROKER_RABBITMQ_ADMIN_USERNAME} + RABBITMQ_DEFAULT_PASS: ${CODEXGO_BROKER_RABBITMQ_ADMIN_PASSWORD} + ports: + - ${CODEXGO_BROKER_RABBITMQ_AMQP_PORT}:5672 + - ${CODEXGO_BROKER_RABBITMQ_ADMIN_PORT}:15672 + restart: ${CODEXGO_BROKER_RABBITMQ_CONTAINER_RESTART} + healthcheck: + test: rabbitmq-diagnostics -q status + interval: 12s + timeout: 12s + retries: 12 + + database-mongodb: + container_name: ${CODEXGO_DATABASE_MONGODB_CONTAINER_NAME} + image: mongo:4.4 + environment: + MONGO_INITDB_ROOT_USERNAME: ${CODEXGO_DATABASE_MONGODB_ROOT_USERNAME} + MONGO_INITDB_ROOT_PASSWORD: ${CODEXGO_DATABASE_MONGODB_ROOT_PASSWORD} + command: mongod --quiet --logpath /dev/null + ports: + - ${CODEXGO_DATABASE_MONGODB_PORT}:27017 + volumes: + - database-mongodb:/data/db + restart: ${CODEXGO_DATABASE_MONGODB_CONTAINER_RESTART} + healthcheck: + test: echo 'db.runCommand({serverStatus:1}).ok' | mongo admin -u ${CODEXGO_DATABASE_MONGODB_ROOT_USERNAME} -p ${CODEXGO_DATABASE_MONGODB_ROOT_PASSWORD} --quiet | grep 1 + interval: 12s + timeout: 12s + retries: 12 + + codexgo: + container_name: ${CODEXGO_CONTAINER_NAME} + image: ${CODEXGO_CONTAINER_IMAGE_TAG} + pull_policy: never + build: + context: .. + dockerfile: deployments/Dockerfile + target: ${CODEXGO_CONTAINER_IMAGE_BUILD_TARGET} + environment: + CODEXGO_BROKER_RABBITMQ_URI: "amqp://${CODEXGO_BROKER_RABBITMQ_ADMIN_USERNAME}:${CODEXGO_BROKER_RABBITMQ_ADMIN_PASSWORD}@broker-rabbitmq:5672" + CODEXGO_BROKER_RABBITMQ_NAME: ${CODEXGO_BROKER_RABBITMQ_NAME} + CODEXGO_DATABASE_MONGODB_URI: "mongodb://${CODEXGO_DATABASE_MONGODB_ROOT_USERNAME}:${CODEXGO_DATABASE_MONGODB_ROOT_PASSWORD}@database-mongodb:27017" + CODEXGO_DATABASE_MONGODB_NAME: ${CODEXGO_DATABASE_MONGODB_NAME} + CODEXGO_SMTP_HOST: ${CODEXGO_SMTP_HOST} + CODEXGO_SMTP_PORT: ${CODEXGO_SMTP_PORT} + CODEXGO_SMTP_USERNAME: ${CODEXGO_SMTP_USERNAME} + CODEXGO_SMTP_PASSWORD: ${CODEXGO_SMTP_PASSWORD} + CODEXGO_JWT_SECRET_KEY: ${CODEXGO_JWT_SECRET_KEY} + CODEXGO_SERVER_GIN_HOSTNAME: ${CODEXGO_SERVER_GIN_HOSTNAME} + CODEXGO_SERVER_GIN_PORT: ${CODEXGO_SERVER_GIN_PORT} + CODEXGO_SERVER_GIN_URL: ${CODEXGO_SERVER_GIN_URL} + CODEXGO_SERVER_GIN_MODE: ${CODEXGO_SERVER_GIN_MODE} + CODEXGO_SERVER_GIN_ALLOWED_HOSTS: ${CODEXGO_SERVER_GIN_ALLOWED_HOSTS} + CODEXGO_SERVER_GIN_COOKIE_SECRET_KEY: ${CODEXGO_SERVER_GIN_COOKIE_SECRET_KEY} + CODEXGO_SERVER_GIN_COOKIE_SESSION_NAME: ${CODEXGO_SERVER_GIN_COOKIE_SESSION_NAME} + CODEXGO_DEV_AIR_PROXY_PORT: ${CODEXGO_DEV_AIR_PROXY_PORT} + command: ${CODEXGO_CONTAINER_START} + ports: + - ${CODEXGO_SERVER_GIN_PORT}:${CODEXGO_SERVER_GIN_PORT} + - ${CODEXGO_DEV_AIR_PROXY_PORT}:${CODEXGO_DEV_AIR_PROXY_PORT} + volumes: + - ${CODEXGO_CONTAINER_VOLUME} + - codexgo-modules:/go/pkg/mod + restart: ${CODEXGO_CONTAINER_RESTART} + depends_on: + broker-rabbitmq: + condition: service_healthy + database-mongodb: + condition: service_healthy + +volumes: + database-mongodb: + name: ${CODEXGO_DATABASE_MONGODB_CONTAINER_VOLUME} + codexgo-logs: + name: codexgo-logs + codexgo-modules: + name: codexgo-modules + +networks: + default: + name: codexgo diff --git a/deployments/run.sh b/deployments/run.sh new file mode 100644 index 0000000..d497c87 --- /dev/null +++ b/deployments/run.sh @@ -0,0 +1,13 @@ +#!/bin/bash + +logs=logs + +today=$(date -u +%d-%m-%Y) + +mkdir -p $logs/$today + +now=$(date -u +%H_%M_%S) + +log=$logs/$today/$now.log + +./codexgo |& tee $log diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..7dca2fe --- /dev/null +++ b/go.mod @@ -0,0 +1,81 @@ +module github.com/bastean/codexgo/v4 + +go 1.23 + +require ( + github.com/JGLTechnologies/gin-rate-limit v1.5.4 + github.com/a-h/templ v0.2.771 + github.com/brianvoe/gofakeit/v7 v7.0.4 + github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be + github.com/cucumber/godog v0.14.1 + github.com/fatih/color v1.17.0 + github.com/gin-contrib/secure v1.1.0 + github.com/gin-contrib/sessions v1.0.1 + github.com/gin-gonic/gin v1.10.0 + github.com/go-playground/validator/v10 v10.22.0 + github.com/golang-jwt/jwt/v5 v5.2.1 + github.com/google/uuid v1.6.0 + github.com/joho/godotenv v1.5.1 + github.com/playwright-community/playwright-go v0.4700.0 + github.com/rabbitmq/amqp091-go v1.10.0 + github.com/stretchr/testify v1.9.0 + go.mongodb.org/mongo-driver v1.16.1 + golang.org/x/crypto v0.27.0 + golang.org/x/text v0.18.0 +) + +require ( + github.com/bytedance/sonic v1.12.2 // indirect + github.com/bytedance/sonic/loader v0.2.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/cloudwego/base64x v0.1.4 // indirect + github.com/cloudwego/iasm v0.2.0 // indirect + github.com/cucumber/gherkin/go/v26 v26.2.0 // indirect + github.com/cucumber/messages/go/v21 v21.0.1 // indirect + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/deckarep/golang-set/v2 v2.6.0 // indirect + github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect + github.com/gabriel-vasile/mimetype v1.4.5 // indirect + github.com/gin-contrib/sse v0.1.0 // indirect + github.com/go-jose/go-jose/v3 v3.0.3 // indirect + github.com/go-playground/locales v0.14.1 // indirect + github.com/go-playground/universal-translator v0.18.1 // indirect + github.com/go-stack/stack v1.8.1 // indirect + github.com/goccy/go-json v0.10.3 // indirect + github.com/gofrs/uuid v4.4.0+incompatible // indirect + github.com/golang/snappy v0.0.4 // indirect + github.com/gorilla/context v1.1.2 // indirect + github.com/gorilla/securecookie v1.1.2 // indirect + github.com/gorilla/sessions v1.4.0 // indirect + github.com/hashicorp/go-immutable-radix v1.3.1 // indirect + github.com/hashicorp/go-memdb v1.3.4 // indirect + github.com/hashicorp/golang-lru v1.0.2 // indirect + github.com/json-iterator/go v1.1.12 // indirect + github.com/klauspost/compress v1.17.9 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect + github.com/leodido/go-urn v1.4.0 // indirect + github.com/mattn/go-colorable v0.1.13 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect + github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect + github.com/modern-go/reflect2 v1.0.2 // indirect + github.com/montanaflynn/stats v0.7.1 // indirect + github.com/pelletier/go-toml/v2 v2.2.3 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + github.com/redis/go-redis/v9 v9.6.1 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/twitchyliquid64/golang-asm v0.15.1 // indirect + github.com/ugorji/go/codec v1.2.12 // indirect + github.com/xdg-go/pbkdf2 v1.0.0 // indirect + github.com/xdg-go/scram v1.1.2 // indirect + github.com/xdg-go/stringprep v1.0.4 // indirect + github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 // indirect + go.uber.org/multierr v1.11.0 // indirect + golang.org/x/arch v0.10.0 // indirect + golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e // indirect + golang.org/x/net v0.29.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.25.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect +) diff --git a/go.sum b/go.sum new file mode 100644 index 0000000..6c25568 --- /dev/null +++ b/go.sum @@ -0,0 +1,242 @@ +github.com/JGLTechnologies/gin-rate-limit v1.5.4 h1:1hIaXIdGM9MZFZlXgjWJLpxaK0WHEa5MeloK49nmQsc= +github.com/JGLTechnologies/gin-rate-limit v1.5.4/go.mod h1:mGEhNzlHEg/Tk+KH/mKylZLTfDjACnx7MVYaAlj07eU= +github.com/a-h/templ v0.2.771 h1:4KH5ykNigYGGpCe0fRJ7/hzwz72k3qFqIiiLLJskbSo= +github.com/a-h/templ v0.2.771/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w= +github.com/brianvoe/gofakeit/v7 v7.0.4 h1:Mkxwz9jYg8Ad8NvT9HA27pCMZGFQo08MK6jD0QTKEww= +github.com/brianvoe/gofakeit/v7 v7.0.4/go.mod h1:QXuPeBw164PJCzCUZVmgpgHJ3Llj49jSLVkKPMtxtxA= +github.com/bsm/ginkgo/v2 v2.12.0 h1:Ny8MWAHyOepLGlLKYmXG4IEkioBysk6GpaRTLC8zwWs= +github.com/bsm/ginkgo/v2 v2.12.0/go.mod h1:SwYbGRRDovPVboqFv0tPTcG1sN61LM1Z4ARdbAV9g4c= +github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= +github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= +github.com/bytedance/sonic v1.12.2 h1:oaMFuRTpMHYLpCntGca65YWt5ny+wAceDERTkT2L9lg= +github.com/bytedance/sonic v1.12.2/go.mod h1:B8Gt/XvtZ3Fqj+iSKMypzymZxw/FVwgIGKzMzT9r/rk= +github.com/bytedance/sonic/loader v0.1.1/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/bytedance/sonic/loader v0.2.0 h1:zNprn+lsIP06C/IqCHs3gPQIvnvpKbbxyXQP1iU4kWM= +github.com/bytedance/sonic/loader v0.2.0/go.mod h1:ncP89zfokxS5LZrJxl5z0UJcsk4M4yY2JpfqGeCtNLU= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cloudwego/base64x v0.1.4 h1:jwCgWpFanWmN8xoIUHa2rtzmkd5J2plF/dnLS6Xd/0Y= +github.com/cloudwego/base64x v0.1.4/go.mod h1:0zlkT4Wn5C6NdauXdJRhSKRlJvmclQ1hhJgA0rcu/8w= +github.com/cloudwego/iasm v0.2.0 h1:1KNIy1I1H9hNNFEEH3DVnI4UujN+1zjpuk6gwHLTssg= +github.com/cloudwego/iasm v0.2.0/go.mod h1:8rXZaNYT2n95jn+zTI1sDr+IgcD2GVs0nlbbQPiEFhY= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be h1:J5BL2kskAlV9ckgEsNQXscjIaLiOYiZ75d4e94E6dcQ= +github.com/common-nighthawk/go-figure v0.0.0-20210622060536-734e95fb86be/go.mod h1:mk5IQ+Y0ZeO87b858TlA645sVcEcbiX6YqP98kt+7+w= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/cucumber/gherkin/go/v26 v26.2.0 h1:EgIjePLWiPeslwIWmNQ3XHcypPsWAHoMCz/YEBKP4GI= +github.com/cucumber/gherkin/go/v26 v26.2.0/go.mod h1:t2GAPnB8maCT4lkHL99BDCVNzCh1d7dBhCLt150Nr/0= +github.com/cucumber/godog v0.14.1 h1:HGZhcOyyfaKclHjJ+r/q93iaTJZLKYW6Tv3HkmUE6+M= +github.com/cucumber/godog v0.14.1/go.mod h1:FX3rzIDybWABU4kuIXLZ/qtqEe1Ac5RdXmqvACJOces= +github.com/cucumber/messages/go/v21 v21.0.1 h1:wzA0LxwjlWQYZd32VTlAVDTkW6inOFmSM+RuOwHZiMI= +github.com/cucumber/messages/go/v21 v21.0.1/go.mod h1:zheH/2HS9JLVFukdrsPWoPdmUtmYQAQPLk7w5vWsk5s= +github.com/cucumber/messages/go/v22 v22.0.0/go.mod h1:aZipXTKc0JnjCsXrJnuZpWhtay93k7Rn3Dee7iyPJjs= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= +github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= +github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/gabriel-vasile/mimetype v1.4.5 h1:J7wGKdGu33ocBOhGy0z653k/lFKLFDPJMG8Gql0kxn4= +github.com/gabriel-vasile/mimetype v1.4.5/go.mod h1:ibHel+/kbxn9x2407k1izTA1S81ku1z/DlgOW2QE0M4= +github.com/gin-contrib/secure v1.1.0 h1:wy/psCWbgUBDCLH13KgB/m06NHXb1jczSTRp+H2hK7E= +github.com/gin-contrib/secure v1.1.0/go.mod h1:LtEfyy326NRwgkUq8ac6npf845L0L9B8yfEaLcxMHIc= +github.com/gin-contrib/sessions v1.0.1 h1:3hsJyNs7v7N8OtelFmYXFrulAf6zSR7nW/putcPEHxI= +github.com/gin-contrib/sessions v1.0.1/go.mod h1:ouxSFM24/OgIud5MJYQJLpy6AwxQ5EYO9yLhbtObGkM= +github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= +github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= +github.com/gin-gonic/gin v1.10.0 h1:nTuyha1TYqgedzytsKYqna+DfLos46nTv2ygFy86HFU= +github.com/gin-gonic/gin v1.10.0/go.mod h1:4PMNQiOhvDRa013RKVbsiNwoyezlm2rm0uX/T7kzp5Y= +github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7G7k= +github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= +github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= +github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= +github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= +github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= +github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= +github.com/go-playground/validator/v10 v10.22.0 h1:k6HsTZ0sTnROkhS//R0O+55JgM8C4Bx7ia+JlgcnOao= +github.com/go-playground/validator/v10 v10.22.0/go.mod h1:dbuPbCMFw/DrkbEynArYaCwl3amGuJotoKCe95atGMM= +github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= +github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= +github.com/goccy/go-json v0.10.3 h1:KZ5WoDbxAIgm2HNbYckL0se1fHD6rz5j4ywS6ebzDqA= +github.com/goccy/go-json v0.10.3/go.mod h1:oq7eo15ShAhp70Anwd5lgX2pLfOS3QCiwU/PULtXL6M= +github.com/gofrs/uuid v4.2.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.3.1+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA= +github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM= +github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= +github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= +github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/gofuzz v1.2.0 h1:xRy4A+RhZaiKjJ1bPfwQ8sedCA+YS2YcCHW6ec7JMi0= +github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gorilla/context v1.1.2 h1:WRkNAv2uoa03QNIc1A6u4O7DAGMUVoopZhkiXWA2V1o= +github.com/gorilla/context v1.1.2/go.mod h1:KDPwT9i/MeWHiLl90fuTgrt4/wPcv75vFAZLaOOcbxM= +github.com/gorilla/securecookie v1.1.2 h1:YCIWL56dvtr73r6715mJs5ZvhtnY73hBvEF8kXD8ePA= +github.com/gorilla/securecookie v1.1.2/go.mod h1:NfCASbcHqRSY+3a8tlWJwsQap2VX5pwzwo4h3eOamfo= +github.com/gorilla/sessions v1.4.0 h1:kpIYOp/oi6MG/p5PgxApU8srsSw9tuFbt46Lt7auzqQ= +github.com/gorilla/sessions v1.4.0/go.mod h1:FLWm50oby91+hl7p/wRxDth9bWSuk0qVL2emc7lT5ik= +github.com/hashicorp/go-immutable-radix v1.3.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-immutable-radix v1.3.1 h1:DKHmCUm2hRBK510BaiZlwvpD40f8bJFeZnpfm2KLowc= +github.com/hashicorp/go-immutable-radix v1.3.1/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= +github.com/hashicorp/go-memdb v1.3.4 h1:XSL3NR682X/cVk2IeV0d70N4DZ9ljI885xAEU8IoK3c= +github.com/hashicorp/go-memdb v1.3.4/go.mod h1:uBTr1oQbtuMgd1SSGoR8YV27eT3sBHbYiNm53bMpgSg= +github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/go-uuid v1.0.2 h1:cfejS+Tpcp13yd5nYHWDI6qVCny6wyX2Mt5SGur2IGE= +github.com/hashicorp/go-uuid v1.0.2/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/golang-lru v1.0.2 h1:dV3g9Z/unq5DpblPpw+Oqcv4dU/1omnb4Ok8iPY6p1c= +github.com/hashicorp/golang-lru v1.0.2/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= +github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= +github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= +github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= +github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= +github.com/klauspost/compress v1.17.9 h1:6KIumPrER1LHsvBVuDa0r5xaG0Es51mhhB9BQB2qeMA= +github.com/klauspost/compress v1.17.9/go.mod h1:Di0epgTjJY877eYKx5yC51cX2A2Vl2ibi7bDH9ttBbw= +github.com/klauspost/cpuid/v2 v2.0.9/go.mod h1:FInQzS24/EEf25PyTYn52gqo7WaD8xa0213Md/qVLRg= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= +github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= +github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= +github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= +github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= +github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= +github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= +github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= +github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= +github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE= +github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/pelletier/go-toml/v2 v2.2.3 h1:YmeHyLY8mFWbdkNWwpr+qIL2bEqT0o95WSdkNHvL12M= +github.com/pelletier/go-toml/v2 v2.2.3/go.mod h1:MfCQTFTvCcUyyvvwm1+G6H/jORL20Xlb6rzQu9GuUkc= +github.com/playwright-community/playwright-go v0.4700.0 h1:Eee2aPPLSgrEbaEZwUVfuczqjCITVf1cEl6EYqh2FI0= +github.com/playwright-community/playwright-go v0.4700.0/go.mod h1:bpArn5TqNzmP0jroCgw4poSOG9gSeQg490iLqWAaa7w= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/rabbitmq/amqp091-go v1.10.0 h1:STpn5XsHlHGcecLmMFCtg7mqq0RnD+zFr4uzukfVhBw= +github.com/rabbitmq/amqp091-go v1.10.0/go.mod h1:Hy4jKW5kQART1u+JkDTF9YYOQUHXqMuhrgxOEeS7G4o= +github.com/redis/go-redis/v9 v9.6.1 h1:HHDteefn6ZkTtY5fGUE8tj8uy85AHk6zP7CpzIAM0y4= +github.com/redis/go-redis/v9 v9.6.1/go.mod h1:0C0c6ycQsdpVNQpxb1njEQIqkx5UcsM8FJCQLgE9+RA= +github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/twitchyliquid64/golang-asm v0.15.1 h1:SU5vSMR7hnwNxj24w34ZyCi/FmDZTkS4MhqMhdFk5YI= +github.com/twitchyliquid64/golang-asm v0.15.1/go.mod h1:a1lVb/DtPvCB8fslRZhAngC2+aY1QWCk3Cedj/Gdt08= +github.com/ugorji/go/codec v1.2.12 h1:9LC83zGrHhuUA9l16C9AHXAqEV/2wBQ4nkvumAE65EE= +github.com/ugorji/go/codec v1.2.12/go.mod h1:UNopzCgEMSXjBc6AOMqYvWC1ktqTAfzJZUZgYf6w6lg= +github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c= +github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= +github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= +github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= +github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= +github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78 h1:ilQV1hzziu+LLM3zUTJ0trRztfwgjqKnBWNtSRkbmwM= +github.com/youmark/pkcs8 v0.0.0-20240726163527-a2c0da244d78/go.mod h1:aL8wCCfTfSfmXjznFBSZNN13rSJjlIOI1fUNAtF7rmI= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +go.mongodb.org/mongo-driver v1.16.1 h1:rIVLL3q0IHM39dvE+z2ulZLp9ENZKThVfuvN/IiN4l8= +go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw= +go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto= +go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE= +go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= +go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= +golang.org/x/arch v0.10.0 h1:S3huipmSclq3PJMNe76NGwkBR504WFkQ5dhzWzP8ZW8= +golang.org/x/arch v0.10.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= +golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= +golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e h1:I88y4caeGeuDQxgdoFPUq097j7kNfw6uvuiNxUBfcBk= +golang.org/x/exp v0.0.0-20240904232852-e7e105dedf7e/go.mod h1:akd2r19cwCdwSwWeIdzYQGa/EZZyqcOdwWiwj5L5eKQ= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= +golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= +golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= +golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/internal/app/cli/cli.go b/internal/app/cli/cli.go new file mode 100644 index 0000000..1ce2993 --- /dev/null +++ b/internal/app/cli/cli.go @@ -0,0 +1,46 @@ +package cli + +import ( + "flag" + "fmt" + + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/logger/log" + "github.com/joho/godotenv" +) + +const ( + cli = "codexgo" +) + +var ( + env string +) + +func usage() { + log.Logo() + + fmt.Print("Example CRUD project applying Hexagonal Architecture, DDD, EDA, CQRS, BDD, CI, and more... in Go.\n\n") + + fmt.Printf("Usage: %s [flags]\n\n", cli) + + flag.PrintDefaults() +} + +func Up() error { + flag.StringVar(&env, "env", "", "Path to ENV file (required)") + + flag.Usage = usage + + flag.Parse() + + if err := godotenv.Load(env); err != nil && env != "" { + return errors.NewInternal(&errors.Bubble{ + Where: "Up", + What: "Failure to load ENV file", + Who: err, + }) + } + + return nil +} diff --git a/internal/app/server/component/layout/index.templ b/internal/app/server/component/layout/index.templ new file mode 100644 index 0000000..dc66558 --- /dev/null +++ b/internal/app/server/component/layout/index.templ @@ -0,0 +1,71 @@ +package layout + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts/fomantic" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts/jquery" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts/storage" +) + +templ Index(headScripts scripts.Head, bodyScripts scripts.Body) { + + + + + + + + + + + + + + + codexGO + + + + + + + + + + + + + + @storage.Init() + + @jquery.Init() + + @fomantic.Init() + + for _, headScript := range headScripts { + @headScript + } + + +

+ for _, bodyScript := range bodyScripts { + @bodyScript + } + + +} diff --git a/internal/app/server/component/layout/index_templ.go b/internal/app/server/component/layout/index_templ.go new file mode 100644 index 0000000..697c78b --- /dev/null +++ b/internal/app/server/component/layout/index_templ.go @@ -0,0 +1,96 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package layout + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts/fomantic" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts/jquery" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts/storage" +) + +func Index(headScripts scripts.Head, bodyScripts scripts.Body) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("codexGO") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = storage.Init().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = jquery.Init().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = fomantic.Init().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, headScript := range headScripts { + templ_7745c5c3_Err = headScript.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ_7745c5c3_Var1.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + for _, bodyScript := range bodyScripts { + templ_7745c5c3_Err = bodyScript.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/page/dashboard/form.delete.templ b/internal/app/server/component/page/dashboard/form.delete.templ new file mode 100644 index 0000000..5701097 --- /dev/null +++ b/internal/app/server/component/page/dashboard/form.delete.templ @@ -0,0 +1,94 @@ +package dashboard + +const ( + DeleteFormTagId = "delete" +) + +script DeleteFormInit(formTagId string) { + $(`#${formTagId}`) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Password: { + rules: [ + { + type: "empty", + prompt: "{name} is required to delete the account" + }, + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + ConfirmPassword: { + rules: [ + { + type: "match[Password]" + } + ] + } + } + }) + .api({ + action: "user_delete", + method: "DELETE", + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + Storage.Clear(); + window.location.replace("/"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +} + +script DeleteFormShow() { + $(".ui.mini.modal").modal("show"); +} + +templ DeleteForm() { + + @DeleteFormInit(DeleteFormTagId) +} diff --git a/internal/app/server/component/page/dashboard/form.delete_templ.go b/internal/app/server/component/page/dashboard/form.delete_templ.go new file mode 100644 index 0000000..35e4d07 --- /dev/null +++ b/internal/app/server/component/page/dashboard/form.delete_templ.go @@ -0,0 +1,132 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package dashboard + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +const ( + DeleteFormTagId = "delete" +) + +func DeleteFormInit(formTagId string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_DeleteFormInit_7477`, + Function: `function __templ_DeleteFormInit_7477(formTagId){$(` + "`" + `#${formTagId}` + "`" + `) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Password: { + rules: [ + { + type: "empty", + prompt: "{name} is required to delete the account" + }, + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + ConfirmPassword: { + rules: [ + { + type: "match[Password]" + } + ] + } + } + }) + .api({ + action: "user_delete", + method: "DELETE", + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + Storage.Clear(); + window.location.replace("/"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +}`, + Call: templ.SafeScript(`__templ_DeleteFormInit_7477`, formTagId), + CallInline: templ.SafeScriptInline(`__templ_DeleteFormInit_7477`, formTagId), + } +} + +func DeleteFormShow() templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_DeleteFormShow_81f8`, + Function: `function __templ_DeleteFormShow_81f8(){$(".ui.mini.modal").modal("show"); +}`, + Call: templ.SafeScript(`__templ_DeleteFormShow_81f8`), + CallInline: templ.SafeScriptInline(`__templ_DeleteFormShow_81f8`), + } +} + +func DeleteForm() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Delete Your Account
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = DeleteFormInit(DeleteFormTagId).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/page/dashboard/form.update.templ b/internal/app/server/component/page/dashboard/form.update.templ new file mode 100644 index 0000000..1b5d080 --- /dev/null +++ b/internal/app/server/component/page/dashboard/form.update.templ @@ -0,0 +1,160 @@ +package dashboard + +const ( + UpdateFormTagId = "update" +) + +script UpdateFormInit(formTagId string) { + $(`#${formTagId}`) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Email: { + optional: true, + rules: [ + { + type: "email" + } + ] + }, + Username: { + optional: true, + rules: [ + { + type: "size[2..20]" + }, + { + type: "regExp[/^[A-Za-z0-9]+$/]", + prompt: "{name} must be alphanumeric only" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + UpdatedPassword: { + optional: true, + rules: [ + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + ConfirmPassword: { + depends: "UpdatedPassword", + rules: [ + { + type: "match[UpdatedPassword]" + } + ] + }, + Password: { + rules: [ + { + type: "empty", + prompt: "{name} is required to update the account settings" + }, + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + } + } + }) + .api({ + action: "user_update", + method: "PATCH", + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + window.location.replace("/dashboard"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +} + +templ UpdateForm(email, username string) { +
+

+ Account settings +

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+ +
+ + +
+
+
+
+
+
+ +
+
+ +
+
+
+
+ @UpdateFormInit(UpdateFormTagId) +} diff --git a/internal/app/server/component/page/dashboard/form.update_templ.go b/internal/app/server/component/page/dashboard/form.update_templ.go new file mode 100644 index 0000000..fca99b7 --- /dev/null +++ b/internal/app/server/component/page/dashboard/form.update_templ.go @@ -0,0 +1,184 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package dashboard + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +const ( + UpdateFormTagId = "update" +) + +func UpdateFormInit(formTagId string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_UpdateFormInit_44f1`, + Function: `function __templ_UpdateFormInit_44f1(formTagId){$(` + "`" + `#${formTagId}` + "`" + `) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Email: { + optional: true, + rules: [ + { + type: "email" + } + ] + }, + Username: { + optional: true, + rules: [ + { + type: "size[2..20]" + }, + { + type: "regExp[/^[A-Za-z0-9]+$/]", + prompt: "{name} must be alphanumeric only" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + UpdatedPassword: { + optional: true, + rules: [ + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + ConfirmPassword: { + depends: "UpdatedPassword", + rules: [ + { + type: "match[UpdatedPassword]" + } + ] + }, + Password: { + rules: [ + { + type: "empty", + prompt: "{name} is required to update the account settings" + }, + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + } + } + }) + .api({ + action: "user_update", + method: "PATCH", + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + window.location.replace("/dashboard"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +}`, + Call: templ.SafeScript(`__templ_UpdateFormInit_44f1`, formTagId), + CallInline: templ.SafeScriptInline(`__templ_UpdateFormInit_44f1`, formTagId), + } +} + +func UpdateForm(email, username string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Account settings

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = UpdateFormInit(UpdateFormTagId).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/page/dashboard/page.dashboard.templ b/internal/app/server/component/page/dashboard/page.dashboard.templ new file mode 100644 index 0000000..7eabd38 --- /dev/null +++ b/internal/app/server/component/page/dashboard/page.dashboard.templ @@ -0,0 +1,112 @@ +package dashboard + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/layout" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" +) + +script PageInit() { + $(".ui.container") + .transition("fade in", "3s") + ; + + $(".ui.menu .right .dropdown") + .dropdown() + ; + + $(".ui.menu .right .header .icon") + .popup() + ; + + $(".ui.blue.nag") + .nag({ + key: "account-confirmation", + value: true + }) + ; + + $(".ui.green.nag") + .nag({ + key: "account-confirmed", + value: true + }) + ; +} + +script Logout() { + Storage.ClearSession(); + window.location.replace("/"); +} + +templ Page(user *user.ReadResponse) { + @layout.Index(scripts.Head{}, scripts.Body{}) { +
+
+ +
+
+ @UpdateForm(user.Email, user.Username) + @DeleteForm() +
+ if !user.Verified { +
+
+ + Account Confirmation +
+
Link sent. Please check your inbox
+ +
+ } else { +
+
+ + Account Confirmed +
+ +
+ } +
+ @PageInit() + } +} diff --git a/internal/app/server/component/page/dashboard/page.dashboard_templ.go b/internal/app/server/component/page/dashboard/page.dashboard_templ.go new file mode 100644 index 0000000..100bf01 --- /dev/null +++ b/internal/app/server/component/page/dashboard/page.dashboard_templ.go @@ -0,0 +1,199 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package dashboard + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/layout" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" +) + +func PageInit() templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_PageInit_cff3`, + Function: `function __templ_PageInit_cff3(){$(".ui.container") + .transition("fade in", "3s") + ; + + $(".ui.menu .right .dropdown") + .dropdown() + ; + + $(".ui.menu .right .header .icon") + .popup() + ; + + $(".ui.blue.nag") + .nag({ + key: "account-confirmation", + value: true + }) + ; + + $(".ui.green.nag") + .nag({ + key: "account-confirmed", + value: true + }) + ; +}`, + Call: templ.SafeScript(`__templ_PageInit_cff3`), + CallInline: templ.SafeScriptInline(`__templ_PageInit_cff3`), + } +} + +func Logout() templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_Logout_55ac`, + Function: `function __templ_Logout_55ac(){Storage.ClearSession(); + window.location.replace("/"); +}`, + Call: templ.SafeScript(`__templ_Logout_55ac`), + CallInline: templ.SafeScriptInline(`__templ_Logout_55ac`), + } +} + +func Page(user *user.ReadResponse) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(user.Username) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `internal/app/server/component/page/dashboard/page.dashboard.templ`, Line: 59, Col: 42} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !user.Verified { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(" ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Account
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, DeleteFormShow()) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Delete
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, Logout()) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Sign out

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = UpdateForm(user.Email, user.Username).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = DeleteForm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + if !user.Verified { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Account Confirmation
Link sent. Please check your inbox
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } else { + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Account Confirmed
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = PageInit().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = layout.Index(scripts.Head{}, scripts.Body{}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/page/home/form.login.templ b/internal/app/server/component/page/home/form.login.templ new file mode 100644 index 0000000..f38d75d --- /dev/null +++ b/internal/app/server/component/page/home/form.login.templ @@ -0,0 +1,84 @@ +package home + +const ( + LoginFormTagId = "login" +) + +script LoginFormInit(formTagId string) { + $(`#${formTagId}`) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Email: { + rules: [ + { + type: "email" + } + ] + }, + Password: { + rules: [ + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + } + } + }) + .api({ + action: "user_login", + method: "POST", + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + window.location.replace("/dashboard"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +} + +templ LoginForm() { +
+

+ Sign in to your account +
Don't have an account? Sign up
+

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ @LoginFormInit(LoginFormTagId) +} diff --git a/internal/app/server/component/page/home/form.login_templ.go b/internal/app/server/component/page/home/form.login_templ.go new file mode 100644 index 0000000..1767a76 --- /dev/null +++ b/internal/app/server/component/page/home/form.login_templ.go @@ -0,0 +1,134 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package home + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +const ( + LoginFormTagId = "login" +) + +func LoginFormInit(formTagId string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_LoginFormInit_a643`, + Function: `function __templ_LoginFormInit_a643(formTagId){$(` + "`" + `#${formTagId}` + "`" + `) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Email: { + rules: [ + { + type: "email" + } + ] + }, + Password: { + rules: [ + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + } + } + }) + .api({ + action: "user_login", + method: "POST", + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + window.location.replace("/dashboard"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +}`, + Call: templ.SafeScript(`__templ_LoginFormInit_a643`, formTagId), + CallInline: templ.SafeScriptInline(`__templ_LoginFormInit_a643`, formTagId), + } +} + +func LoginForm() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Sign in to your account
Don't have an account? ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, ShowTab(RegisterTabTagId)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Sign up

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = LoginFormInit(LoginFormTagId).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/page/home/form.register.templ b/internal/app/server/component/page/home/form.register.templ new file mode 100644 index 0000000..9e78d60 --- /dev/null +++ b/internal/app/server/component/page/home/form.register.templ @@ -0,0 +1,150 @@ +package home + +const ( + RegisterFormTagId = "register" +) + +script RegisterFormInit(formTagId, loginTabTagId string) { + $(`#${formTagId}`) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Email: { + rules: [ + { + type: "email" + } + ] + }, + Username: { + rules: [ + { + type: "size[2..20]" + }, + { + type: "regExp[/^[A-Za-z0-9]+$/]", + prompt: "{name} must be alphanumeric only" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + Password: { + rules: [ + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + ConfirmPassword: { + rules: [ + { + type: "match[Password]" + } + ] + }, + Terms: { + rules: [ + { + type: "checked", + prompt: "Terms and Conditions must be checked" + } + ] + } + } + }) + .api({ + action: "user_create", + method: "PUT", + beforeSend: function(settings) { + settings.data.Id = crypto.randomUUID(); + + settings.data = JSON.stringify(settings.data); + + return settings; + }, + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + $.tab("change tab", loginTabTagId); + $(`#${formTagId}`).form("reset"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +} + +script ShowTerms(modalTagId string) { + $(`#${modalTagId}`).modal("show"); +} + +templ RegisterForm() { +
+

+ Create an account +
Already have an account? Sign in
+

+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+ +
+ + +
+
+
+
+
+
+
+ + +
+
+ +
+
+
+ @RegisterFormInit(RegisterFormTagId, LoginTabTagId) +} diff --git a/internal/app/server/component/page/home/form.register_templ.go b/internal/app/server/component/page/home/form.register_templ.go new file mode 100644 index 0000000..fc7658b --- /dev/null +++ b/internal/app/server/component/page/home/form.register_templ.go @@ -0,0 +1,199 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package home + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +const ( + RegisterFormTagId = "register" +) + +func RegisterFormInit(formTagId, loginTabTagId string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_RegisterFormInit_2940`, + Function: `function __templ_RegisterFormInit_2940(formTagId, loginTabTagId){$(` + "`" + `#${formTagId}` + "`" + `) + .form({ + on: "blur", + inline: true, + preventLeaving: true, + keyboardShortcuts: false, + fields: { + Email: { + rules: [ + { + type: "email" + } + ] + }, + Username: { + rules: [ + { + type: "size[2..20]" + }, + { + type: "regExp[/^[A-Za-z0-9]+$/]", + prompt: "{name} must be alphanumeric only" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + Password: { + rules: [ + { + type: "size[8..64]" + }, + { + type: "regExp[/^.*[^0-9].*$/]", + prompt: "{name} cannot be only numbers" + } + ] + }, + ConfirmPassword: { + rules: [ + { + type: "match[Password]" + } + ] + }, + Terms: { + rules: [ + { + type: "checked", + prompt: "Terms and Conditions must be checked" + } + ] + } + } + }) + .api({ + action: "user_create", + method: "PUT", + beforeSend: function(settings) { + settings.data.Id = crypto.randomUUID(); + + settings.data = JSON.stringify(settings.data); + + return settings; + }, + onSuccess: function(response, element, xhr) { + $.toast({ + class: "success", + message: response.Message, + showProgress: "top" + }); + + _.delay(function() { + $.tab("change tab", loginTabTagId); + $(` + "`" + `#${formTagId}` + "`" + `).form("reset"); + }, 1000); + }, + onFailure: function(response, element, xhr) { + $.toast({ + class: "error", + message: response.Message, + showProgress: "top" + }); + } + }) + ; +}`, + Call: templ.SafeScript(`__templ_RegisterFormInit_2940`, formTagId, loginTabTagId), + CallInline: templ.SafeScriptInline(`__templ_RegisterFormInit_2940`, formTagId, loginTabTagId), + } +} + +func ShowTerms(modalTagId string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_ShowTerms_9e12`, + Function: `function __templ_ShowTerms_9e12(modalTagId){$(` + "`" + `#${modalTagId}` + "`" + `).modal("show"); +}`, + Call: templ.SafeScript(`__templ_ShowTerms_9e12`, modalTagId), + CallInline: templ.SafeScriptInline(`__templ_ShowTerms_9e12`, modalTagId), + } +} + +func RegisterForm() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Create an account
Already have an account? ") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, ShowTab(LoginTabTagId)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("Sign in

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = templ.RenderScriptItems(ctx, templ_7745c5c3_Buffer, ShowTerms(TermsModalTagId)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = RegisterFormInit(RegisterFormTagId, LoginTabTagId).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/page/home/modal.terms.templ b/internal/app/server/component/page/home/modal.terms.templ new file mode 100644 index 0000000..c58e892 --- /dev/null +++ b/internal/app/server/component/page/home/modal.terms.templ @@ -0,0 +1,36 @@ +package home + +const ( + TermsModalTagId = "terms" +) + +templ TermsModal() { + +} diff --git a/internal/app/server/component/page/home/modal.terms_templ.go b/internal/app/server/component/page/home/modal.terms_templ.go new file mode 100644 index 0000000..bf99ff4 --- /dev/null +++ b/internal/app/server/component/page/home/modal.terms_templ.go @@ -0,0 +1,54 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package home + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +const ( + TermsModalTagId = "terms" +) + +func TermsModal() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
Terms and Conditions
Disclaimers

The information provided by codexGO (\"we,\" \"us,\" or \"our\") on codexgo.bastean.dev (the \"Site\") and our mobile application is for general informational purposes only. All information on the Site and our mobile application is provided in good faith, however we make no representation or warranty of any kind, express or implied, regarding the accuracy, adequacy, validity, reliability, availability, or completeness of any information on the Site or our mobile application.

UNDER NO CIRCUMSTANCE SHALL WE HAVE ANY LIABILITY TO YOU FOR ANY LOSS OR DAMAGE OF ANY KIND INCURRED AS A RESULT OF THE USE OF THE SITE OR OUR MOBILE APPLICATION OR RELIANCE ON ANY INFORMATION PROVIDED ON THE SITE AND OUR MOBILE APPLICATION. YOUR USE OF THE SITE AND OUR MOBILE APPLICATION AND YOUR RELIANCE ON ANY INFORMATION ON THE SITE AND OUR MOBILE APPLICATION IS SOLELY AT YOUR OWN RISK.

The Site and our mobile application may contain (or you may be sent through the Site or our mobile application) links to other websites or content belonging to or originating from third parties or links to websites and features in banners or other advertising. Such external links are not investigated, monitored, or checked for accuracy, adequacy, validity, reliability, availability, or completeness by us.

WE DO NOT WARRANT, ENDORSE, GUARANTEE, OR ASSUME RESPONSIBILITY FOR THE ACCURACY OR RELIABILITY OF ANY INFORMATION OFFERED BY THIRD-PARTY WEBSITES LINKED THROUGH THE SITE OR ANY WEBSITE OR FEATURE LINKED IN ANY BANNER OR OTHER ADVERTISING. WE WILL NOT BE A PARTY TO OR IN ANY WAY BE RESPONSIBLE FOR MONITORING ANY TRANSACTION BETWEEN YOU AND THIRD-PARTY PROVIDERS OF PRODUCTS OR SERVICES.
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/page/home/page.home.templ b/internal/app/server/component/page/home/page.home.templ new file mode 100644 index 0000000..4ef7655 --- /dev/null +++ b/internal/app/server/component/page/home/page.home.templ @@ -0,0 +1,73 @@ +package home + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/layout" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts" +) + +const ( + RegisterTabTagId = "tab-register" + LoginTabTagId = "tab-login" +) + +script PageInit() { + $(".ui.container") + .transition("fade in", "3s") + ; + + $(".ui.container .column .menu .right .item") + .tab({ + context: ".container" + }) + ; + + $(".ui.cookie.nag") + .nag({ + key: "accepts-cookies", + value: true + }) + ; +} + +script ShowTab(tabTagId string) { + $(`.ui.menu .right .item[data-tab=${tabTagId}]`).trigger("click"); +} + +templ Page() { + @layout.Index(scripts.Head{}, scripts.Body{}) { +
+
+ +
+
+
+ @RegisterForm() + @TermsModal() +
+
+ @LoginForm() +
+
+ +
+ @PageInit() + } +} diff --git a/internal/app/server/component/page/home/page.home_templ.go b/internal/app/server/component/page/home/page.home_templ.go new file mode 100644 index 0000000..5479d0c --- /dev/null +++ b/internal/app/server/component/page/home/page.home_templ.go @@ -0,0 +1,176 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package home + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/layout" + "github.com/bastean/codexgo/v4/internal/app/server/component/scripts" +) + +const ( + RegisterTabTagId = "tab-register" + LoginTabTagId = "tab-login" +) + +func PageInit() templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_PageInit_d7f3`, + Function: `function __templ_PageInit_d7f3(){$(".ui.container") + .transition("fade in", "3s") + ; + + $(".ui.container .column .menu .right .item") + .tab({ + context: ".container" + }) + ; + + $(".ui.cookie.nag") + .nag({ + key: "accepts-cookies", + value: true + }) + ; +}`, + Call: templ.SafeScript(`__templ_PageInit_d7f3`), + CallInline: templ.SafeScriptInline(`__templ_PageInit_d7f3`), + } +} + +func ShowTab(tabTagId string) templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_ShowTab_ce29`, + Function: `function __templ_ShowTab_ce29(tabTagId){$(` + "`" + `.ui.menu .right .item[data-tab=${tabTagId}]` + "`" + `).trigger("click"); +}`, + Call: templ.SafeScript(`__templ_ShowTab_ce29`, tabTagId), + CallInline: templ.SafeScriptInline(`__templ_ShowTab_ce29`, tabTagId), + } +} + +func Page() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + templ_7745c5c3_Var2 := templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = RegisterForm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = TermsModal().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = LoginForm().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
We use cookies to ensure you get the best experience on our website
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = PageInit().Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) + templ_7745c5c3_Err = layout.Index(scripts.Head{}, scripts.Body{}).Render(templ.WithChildren(ctx, templ_7745c5c3_Var2), templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/scripts/fomantic/fomantic.templ b/internal/app/server/component/scripts/fomantic/fomantic.templ new file mode 100644 index 0000000..b869548 --- /dev/null +++ b/internal/app/server/component/scripts/fomantic/fomantic.templ @@ -0,0 +1,34 @@ +package fomantic + +script Init() { + user = { + "user_create" : "/v4/account", + "user_login" : "/v4/account", + "user_update" : "/v4/account", + "user_delete" : "/v4/account", + }; + + $.api.settings.api = { + ...user, + }; + + $.api.settings.serializeForm = true; + + $.api.settings.contentType = "application/json; charset=UTF-8"; + + $.api.settings.beforeSend = function(settings) { + settings.data = JSON.stringify(settings.data); + return settings; + }; + + $.api.settings.successTest = function(response) { + if(response && response.Success) { + return response.Success; + } + + return false; + }; +} + +templ Fomantic() { +} diff --git a/internal/app/server/component/scripts/fomantic/fomantic_templ.go b/internal/app/server/component/scripts/fomantic/fomantic_templ.go new file mode 100644 index 0000000..4cca393 --- /dev/null +++ b/internal/app/server/component/scripts/fomantic/fomantic_templ.go @@ -0,0 +1,69 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package fomantic + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func Init() templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_Init_24bf`, + Function: `function __templ_Init_24bf(){user = { + "user_create" : "/v4/account", + "user_login" : "/v4/account", + "user_update" : "/v4/account", + "user_delete" : "/v4/account", + }; + + $.api.settings.api = { + ...user, + }; + + $.api.settings.serializeForm = true; + + $.api.settings.contentType = "application/json; charset=UTF-8"; + + $.api.settings.beforeSend = function(settings) { + settings.data = JSON.stringify(settings.data); + return settings; + }; + + $.api.settings.successTest = function(response) { + if(response && response.Success) { + return response.Success; + } + + return false; + }; +}`, + Call: templ.SafeScript(`__templ_Init_24bf`), + CallInline: templ.SafeScriptInline(`__templ_Init_24bf`), + } +} + +func Fomantic() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/scripts/jquery/jquery.templ b/internal/app/server/component/scripts/jquery/jquery.templ new file mode 100644 index 0000000..932815d --- /dev/null +++ b/internal/app/server/component/scripts/jquery/jquery.templ @@ -0,0 +1,9 @@ +package jquery + +script Init() { + //? $(document).ready(handler) + $(() => {}); +} + +templ JQuery() { +} diff --git a/internal/app/server/component/scripts/jquery/jquery_templ.go b/internal/app/server/component/scripts/jquery/jquery_templ.go new file mode 100644 index 0000000..c9b71ce --- /dev/null +++ b/internal/app/server/component/scripts/jquery/jquery_templ.go @@ -0,0 +1,44 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package jquery + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func Init() templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_Init_559e`, + Function: `function __templ_Init_559e(){//? $(document).ready(handler) + $(() => {}); +}`, + Call: templ.SafeScript(`__templ_Init_559e`), + CallInline: templ.SafeScriptInline(`__templ_Init_559e`), + } +} + +func JQuery() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/scripts/scripts.templ b/internal/app/server/component/scripts/scripts.templ new file mode 100644 index 0000000..d92e08b --- /dev/null +++ b/internal/app/server/component/scripts/scripts.templ @@ -0,0 +1,9 @@ +package scripts + +type ( + Head = []templ.ComponentScript + Body = []templ.ComponentScript +) + +templ Scripts() { +} diff --git a/internal/app/server/component/scripts/scripts_templ.go b/internal/app/server/component/scripts/scripts_templ.go new file mode 100644 index 0000000..637ea3b --- /dev/null +++ b/internal/app/server/component/scripts/scripts_templ.go @@ -0,0 +1,38 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package scripts + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +type ( + Head = []templ.ComponentScript + Body = []templ.ComponentScript +) + +func Scripts() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/component/scripts/storage/storage.templ b/internal/app/server/component/scripts/storage/storage.templ new file mode 100644 index 0000000..51bdf18 --- /dev/null +++ b/internal/app/server/component/scripts/storage/storage.templ @@ -0,0 +1,60 @@ +package storage + +script Init() { + const Storage = { + MasterKey: "codexgo", + Key: {}, + Init() { + let storage = localStorage.getItem(this.MasterKey); + + if (storage == null) { + localStorage.setItem(this.MasterKey, JSON.stringify({})); + } + }, + Put(key, value) { + let storage = localStorage.getItem(this.MasterKey); + + storage = JSON.parse(storage) + + storage[key] = value; + + localStorage.setItem(this.MasterKey, JSON.stringify(storage)); + }, + Get(key) { + let storage = localStorage.getItem(this.MasterKey); + + storage = JSON.parse(storage) + + return _.get(storage, key, null); + }, + Delete(key) { + let storage = localStorage.getItem(this.MasterKey); + + storage = JSON.parse(storage) + + delete storage[key]; + + localStorage.setItem(this.MasterKey, JSON.stringify(storage)); + }, + async ClearSession() { + localStorage.removeItem(this.MasterKey); + cookieStore.delete(this.MasterKey); + }, + async Clear() { + localStorage.clear(); + + let cookies = await cookieStore.getAll(); + + _.each(cookies, function(cookie) { + cookieStore.delete(cookie); + }); + } + } + + Storage.Init(); + + window.Storage = Storage +} + +templ Storage() { +} diff --git a/internal/app/server/component/scripts/storage/storage_templ.go b/internal/app/server/component/scripts/storage/storage_templ.go new file mode 100644 index 0000000..e0e5e0a --- /dev/null +++ b/internal/app/server/component/scripts/storage/storage_templ.go @@ -0,0 +1,95 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package storage + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func Init() templ.ComponentScript { + return templ.ComponentScript{ + Name: `__templ_Init_9d44`, + Function: `function __templ_Init_9d44(){const Storage = { + MasterKey: "codexgo", + Key: {}, + Init() { + let storage = localStorage.getItem(this.MasterKey); + + if (storage == null) { + localStorage.setItem(this.MasterKey, JSON.stringify({})); + } + }, + Put(key, value) { + let storage = localStorage.getItem(this.MasterKey); + + storage = JSON.parse(storage) + + storage[key] = value; + + localStorage.setItem(this.MasterKey, JSON.stringify(storage)); + }, + Get(key) { + let storage = localStorage.getItem(this.MasterKey); + + storage = JSON.parse(storage) + + return _.get(storage, key, null); + }, + Delete(key) { + let storage = localStorage.getItem(this.MasterKey); + + storage = JSON.parse(storage) + + delete storage[key]; + + localStorage.setItem(this.MasterKey, JSON.stringify(storage)); + }, + async ClearSession() { + localStorage.removeItem(this.MasterKey); + cookieStore.delete(this.MasterKey); + }, + async Clear() { + localStorage.clear(); + + let cookies = await cookieStore.getAll(); + + _.each(cookies, function(cookie) { + cookieStore.delete(cookie); + }); + } + } + + Storage.Init(); + + window.Storage = Storage +}`, + Call: templ.SafeScript(`__templ_Init_9d44`), + CallInline: templ.SafeScriptInline(`__templ_Init_9d44`), + } +} + +func Storage() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/internal/app/server/features/redirect/default.feature b/internal/app/server/features/redirect/default.feature new file mode 100644 index 0000000..64b2799 --- /dev/null +++ b/internal/app/server/features/redirect/default.feature @@ -0,0 +1,6 @@ +Feature: Default Redirect + + Scenario: Check the correct redirect for not found page + Given I am on /non-existing page + Then redirect me to / page + And the page title should be codexGO diff --git a/internal/app/server/features/user/create.feature b/internal/app/server/features/user/create.feature new file mode 100644 index 0000000..9da708c --- /dev/null +++ b/internal/app/server/features/user/create.feature @@ -0,0 +1,21 @@ +Feature: Create a new user account + + Scenario: Create a valid non existing account + Given I am on / page + Then I fill the Email with create@example.com + * I fill the Username with create + * I fill the Password with create@example + * I fill the Confirm Password with create@example + * I check the I agree to the terms and conditions + * I click the Sign up button + And I see Account created notification + + Scenario: Create already existing account + Given I am on / page + Then I fill the Email with create@example.com + * I fill the Username with create + * I fill the Password with create@example + * I fill the Confirm Password with create@example + * I check the I agree to the terms and conditions + * I click the Sign up button + But I see Email already registered notification diff --git a/internal/app/server/features/user/delete.feature b/internal/app/server/features/user/delete.feature new file mode 100644 index 0000000..3de1f98 --- /dev/null +++ b/internal/app/server/features/user/delete.feature @@ -0,0 +1,30 @@ +Feature: Delete a user account + + Scenario: Create a valid non existing account + Given I am on / page + Then I fill the Email with delete@example.com + * I fill the Username with delete + * I fill the Password with delete@example + * I fill the Confirm Password with delete@example + * I check the I agree to the terms and conditions + * I click the Sign up button + And I see Account created notification + + Scenario: Login a valid existing account + Given I am on / page + Then I click on the Sign in button + * I fill the Email with delete@example.com + * I fill the Password with delete@example + * I click the Sign in button + * I see Logged in notification + And redirect me to /dashboard page + + Scenario: Delete a valid existing account + Given I am on /dashboard page + Then I open the account menu + * I click on the Delete button + * I fill the Password with delete@example + * I fill the Confirm Password with delete@example + * I click the Approve button + * I see Account deleted notification + And redirect me to / page diff --git a/internal/app/server/features/user/login.feature b/internal/app/server/features/user/login.feature new file mode 100644 index 0000000..5873a56 --- /dev/null +++ b/internal/app/server/features/user/login.feature @@ -0,0 +1,28 @@ +Feature: Login a user account + + Scenario: Create a valid non existing account + Given I am on / page + Then I fill the Email with login@example.com + * I fill the Username with login + * I fill the Password with login@example + * I fill the Confirm Password with login@example + * I check the I agree to the terms and conditions + * I click the Sign up button + And I see Account created notification + + Scenario: Login a valid existing account + Given I am on / page + Then I click on the Sign in button + * I fill the Email with login@example.com + * I fill the Password with login@example + * I click the Sign in button + * I see Logged in notification + And redirect me to /dashboard page + + Scenario: Login a valid non existing account + Given I am on / page + Then I click on the Sign in button + * I fill the Email with non-existing@example.com + * I fill the Password with non-existing@example + * I click the Sign in button + But I see non-existing@example.com not found notification diff --git a/internal/app/server/features/user/update.feature b/internal/app/server/features/user/update.feature new file mode 100644 index 0000000..a6d200b --- /dev/null +++ b/internal/app/server/features/user/update.feature @@ -0,0 +1,30 @@ +Feature: Update a user account + + Scenario: Create a valid non existing account + Given I am on / page + Then I fill the Email with update@example.com + * I fill the Username with update + * I fill the Password with update@example + * I fill the Confirm Password with update@example + * I check the I agree to the terms and conditions + * I click the Sign up button + And I see Account created notification + + Scenario: Login a valid existing account + Given I am on / page + Then I click on the Sign in button + * I fill the Email with update@example.com + * I fill the Password with update@example + * I click the Sign in button + * I see Logged in notification + And redirect me to /dashboard page + + Scenario: Update a valid existing account + Given I am on /dashboard page + Then I fill the Email with updated@example.com + * I fill the Username with updated + * I fill the New Password with updated@example + * I fill the Confirm Password with updated@example + * I fill the Current Password with update@example + * I click the Update button + And I see Account updated notification diff --git a/internal/app/server/handler/health/check.go b/internal/app/server/handler/health/check.go new file mode 100644 index 0000000..1285c67 --- /dev/null +++ b/internal/app/server/handler/health/check.go @@ -0,0 +1,11 @@ +package health + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func Check(c *gin.Context) { + c.Status(http.StatusOK) +} diff --git a/internal/app/server/handler/page/dashboard.go b/internal/app/server/handler/page/dashboard.go new file mode 100644 index 0000000..9d0a7a2 --- /dev/null +++ b/internal/app/server/handler/page/dashboard.go @@ -0,0 +1,37 @@ +package page + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/page/dashboard" + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/bastean/codexgo/v4/internal/app/server/util/format" + "github.com/bastean/codexgo/v4/internal/app/server/util/key" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" + "github.com/gin-gonic/gin" +) + +func Dashboard(c *gin.Context) { + id, exists := c.Get(key.UserId) + + if !exists { + errs.AbortErrWithRedirect(c, errs.MissingKey(key.UserId, "Dashboard"), "/") + return + } + + query := new(user.ReadQuery) + + query.Id = format.ToString(id) + + found, err := user.Read.Handle(query) + + if err != nil { + errs.AbortErrWithRedirect(c, errors.BubbleUp(err, "Dashboard"), "/") + return + } + + err = dashboard.Page(found).Render(c.Request.Context(), c.Writer) + + if err != nil { + errs.AbortErr(c, errs.Render(err, "Dashboard")) + } +} diff --git a/internal/app/server/handler/page/home.go b/internal/app/server/handler/page/home.go new file mode 100644 index 0000000..95e5504 --- /dev/null +++ b/internal/app/server/handler/page/home.go @@ -0,0 +1,13 @@ +package page + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/component/page/home" + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/gin-gonic/gin" +) + +func Home(c *gin.Context) { + if err := home.Page().Render(c.Request.Context(), c.Writer); err != nil { + errs.AbortErr(c, errs.Render(err, "Home")) + } +} diff --git a/internal/app/server/handler/redirect/default.go b/internal/app/server/handler/redirect/default.go new file mode 100644 index 0000000..706f1c2 --- /dev/null +++ b/internal/app/server/handler/redirect/default.go @@ -0,0 +1,11 @@ +package redirect + +import ( + "net/http" + + "github.com/gin-gonic/gin" +) + +func Default(c *gin.Context) { + c.Redirect(http.StatusFound, "/") +} diff --git a/internal/app/server/handler/user/create.go b/internal/app/server/handler/user/create.go new file mode 100644 index 0000000..46a7e38 --- /dev/null +++ b/internal/app/server/handler/user/create.go @@ -0,0 +1,34 @@ +package user + +import ( + "net/http" + + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/bastean/codexgo/v4/internal/app/server/util/reply" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" + "github.com/gin-gonic/gin" +) + +func Create(c *gin.Context) { + command := new(user.CreateCommand) + + err := c.BindJSON(command) + + if err != nil { + errs.AbortErr(c, errs.BindingJSON(err, "Create")) + return + } + + err = user.Create.Handle(command) + + if err != nil { + errs.AbortErr(c, errors.BubbleUp(err, "Create")) + return + } + + c.JSON(http.StatusCreated, &reply.JSON{ + Success: true, + Message: "Account created", + }) +} diff --git a/internal/app/server/handler/user/delete.go b/internal/app/server/handler/user/delete.go new file mode 100644 index 0000000..c4acd9e --- /dev/null +++ b/internal/app/server/handler/user/delete.go @@ -0,0 +1,62 @@ +package user + +import ( + "net/http" + + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/bastean/codexgo/v4/internal/app/server/util/format" + "github.com/bastean/codexgo/v4/internal/app/server/util/key" + "github.com/bastean/codexgo/v4/internal/app/server/util/reply" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" +) + +func Delete(c *gin.Context) { + id, exists := c.Get(key.UserId) + + if !exists { + errs.AbortErr(c, errs.MissingKey(key.UserId, "Delete")) + return + } + + command := new(user.DeleteCommand) + + err := c.BindJSON(command) + + if err != nil { + errs.AbortErr(c, errs.BindingJSON(err, "Delete")) + return + } + + command.Id = format.ToString(id) + + err = user.Delete.Handle(command) + + if err != nil { + errs.AbortErr(c, errors.BubbleUp(err, "Delete")) + return + } + + session := sessions.Default(c) + + session.Clear() + + session.Options(sessions.Options{ + Path: "/", + MaxAge: -1, + }) + + err = session.Save() + + if err != nil { + errs.AbortErr(c, errs.SessionSave(err, "Delete")) + return + } + + c.JSON(http.StatusOK, &reply.JSON{ + Success: true, + Message: "Account deleted", + }) +} diff --git a/internal/app/server/handler/user/login.go b/internal/app/server/handler/user/login.go new file mode 100644 index 0000000..2ffaa9b --- /dev/null +++ b/internal/app/server/handler/user/login.go @@ -0,0 +1,59 @@ +package user + +import ( + "net/http" + "time" + + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/bastean/codexgo/v4/internal/app/server/util/key" + "github.com/bastean/codexgo/v4/internal/app/server/util/reply" + "github.com/bastean/codexgo/v4/internal/pkg/service/authentication/jwt" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" +) + +func Login(c *gin.Context) { + query := new(user.LoginQuery) + + err := c.BindJSON(query) + + if err != nil { + errs.AbortErr(c, errs.BindingJSON(err, "Login")) + return + } + + found, err := user.Login.Handle(query) + + if err != nil { + errs.AbortErr(c, errors.BubbleUp(err, "Login")) + return + } + + token, err := jwt.Generate(jwt.Payload{ + key.Exp: time.Now().Add((24 * time.Hour) * 7).Unix(), + key.UserId: found.Id, + }) + + if err != nil { + errs.AbortErr(c, errors.BubbleUp(err, "Login")) + return + } + + session := sessions.Default(c) + + session.Set(key.Authorization, "Bearer "+token) + + err = session.Save() + + if err != nil { + errs.AbortErr(c, errs.SessionSave(err, "Login")) + return + } + + c.JSON(http.StatusOK, &reply.JSON{ + Success: true, + Message: "Logged in", + }) +} diff --git a/internal/app/server/handler/user/update.go b/internal/app/server/handler/user/update.go new file mode 100644 index 0000000..4918d03 --- /dev/null +++ b/internal/app/server/handler/user/update.go @@ -0,0 +1,45 @@ +package user + +import ( + "net/http" + + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/bastean/codexgo/v4/internal/app/server/util/format" + "github.com/bastean/codexgo/v4/internal/app/server/util/key" + "github.com/bastean/codexgo/v4/internal/app/server/util/reply" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" + "github.com/gin-gonic/gin" +) + +func Update(c *gin.Context) { + id, exists := c.Get(key.UserId) + + if !exists { + errs.AbortErr(c, errs.MissingKey(key.UserId, "Update")) + return + } + + command := new(user.UpdateCommand) + + err := c.BindJSON(command) + + if err != nil { + errs.AbortErr(c, errs.BindingJSON(err, "Update")) + return + } + + command.Id = format.ToString(id) + + err = user.Update.Handle(command) + + if err != nil { + errs.AbortErr(c, errors.BubbleUp(err, "Update")) + return + } + + c.JSON(http.StatusOK, &reply.JSON{ + Success: true, + Message: "Account updated", + }) +} diff --git a/internal/app/server/handler/user/verify.go b/internal/app/server/handler/user/verify.go new file mode 100644 index 0000000..990ebac --- /dev/null +++ b/internal/app/server/handler/user/verify.go @@ -0,0 +1,33 @@ +package user + +import ( + "net/http" + + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/bastean/codexgo/v4/internal/app/server/util/key" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/module/user" + "github.com/gin-gonic/gin" +) + +func Verify(c *gin.Context) { + id := c.Param(key.Id) + + if id == "" { + errs.AbortErrWithRedirect(c, errs.MissingKey(key.Id, "Verify"), "/") + return + } + + command := new(user.VerifyCommand) + + command.Id = id + + err := user.Verify.Handle(command) + + if err != nil { + errs.AbortErr(c, errors.BubbleUp(err, "Verify")) + return + } + + c.Redirect(http.StatusFound, "/dashboard") +} diff --git a/internal/app/server/middleware/authentication.go b/internal/app/server/middleware/authentication.go new file mode 100644 index 0000000..c296497 --- /dev/null +++ b/internal/app/server/middleware/authentication.go @@ -0,0 +1,44 @@ +package middleware + +import ( + "strings" + + "github.com/bastean/codexgo/v4/internal/app/server/util/errs" + "github.com/bastean/codexgo/v4/internal/app/server/util/format" + "github.com/bastean/codexgo/v4/internal/app/server/util/key" + "github.com/bastean/codexgo/v4/internal/pkg/service/authentication/jwt" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/gin-contrib/sessions" + "github.com/gin-gonic/gin" +) + +func Authentication(c *gin.Context) { + session := sessions.Default(c) + + token := session.Get(key.Authorization) + + if token == nil { + errs.AbortWithRedirect(c, "/") + return + } + + signature := strings.Split(format.ToString(token), " ")[1] + + claims, err := jwt.Validate(signature) + + if err != nil { + errs.AbortErrWithRedirect(c, errors.BubbleUp(err, "Authentication"), "/") + return + } + + value, exists := claims[key.UserId] + + if !exists { + errs.AbortErrWithRedirect(c, errs.MissingKey(key.UserId, "Authentication"), "/") + return + } + + c.Set(key.UserId, value) + + c.Next() +} diff --git a/internal/app/server/middleware/cookie.go b/internal/app/server/middleware/cookie.go new file mode 100644 index 0000000..6002d65 --- /dev/null +++ b/internal/app/server/middleware/cookie.go @@ -0,0 +1,15 @@ +package middleware + +import ( + "github.com/bastean/codexgo/v4/internal/pkg/service/env" + "github.com/gin-contrib/sessions" + "github.com/gin-contrib/sessions/cookie" + "github.com/gin-gonic/gin" +) + +func CookieSession() gin.HandlerFunc { + return sessions.Sessions( + env.ServerGinCookieSessionName, + cookie.NewStore([]byte(env.ServerGinCookieSecretKey)), + ) +} diff --git a/internal/app/server/middleware/error.go b/internal/app/server/middleware/error.go new file mode 100644 index 0000000..9393212 --- /dev/null +++ b/internal/app/server/middleware/error.go @@ -0,0 +1,82 @@ +package middleware + +import ( + "net/http" + + "github.com/bastean/codexgo/v4/internal/app/server/util/key" + "github.com/bastean/codexgo/v4/internal/app/server/util/reply" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/logger/log" + "github.com/gin-gonic/gin" +) + +type ErrorResponse struct { + Status int + *reply.JSON +} + +func ErrorHandler() gin.HandlerFunc { + return func(c *gin.Context) { + c.Next() + + var ( + errInvalidValue *errors.ErrInvalidValue + errAlreadyExist *errors.ErrAlreadyExist + errNotExist *errors.ErrNotExist + errFailure *errors.ErrFailure + errInternal *errors.ErrInternal + ) + + if len(c.Errors) == 0 { + return + } + + var response *ErrorResponse + + err := c.Errors[len(c.Errors)-1] + + switch { + case errors.As(err, &errInvalidValue): + response = &ErrorResponse{http.StatusUnprocessableEntity, &reply.JSON{Message: errInvalidValue.What, Data: errInvalidValue.Why}} + case errors.As(err, &errAlreadyExist): + response = &ErrorResponse{http.StatusConflict, &reply.JSON{Message: errAlreadyExist.What, Data: errAlreadyExist.Why}} + case errors.As(err, &errNotExist): + response = &ErrorResponse{http.StatusNotFound, &reply.JSON{Message: errNotExist.What, Data: errNotExist.Why}} + case errors.As(err, &errFailure): + response = &ErrorResponse{http.StatusBadRequest, &reply.JSON{Message: errFailure.What, Data: errFailure.Why}} + case errors.As(err, &errInternal): + response = &ErrorResponse{http.StatusInternalServerError, &reply.JSON{Message: "Server error. Try again later."}} + fallthrough + case err != nil: + log.Error(err.Error()) + } + + if route, shouldRedirect := c.Get(key.Redirect); shouldRedirect { + if response != nil { + log.Error(err.Error()) + } + + route, ok := route.(string) + + if !ok { + log.Error(errors.NewInternal(&errors.Bubble{ + Where: "ErrorHandler", + What: "Invalid redirection Route", + Why: errors.Meta{ + "Route": route, + }, + }).Error()) + + route = "/" + } + + c.Redirect(http.StatusFound, route) + + return + } + + if response != nil { + c.JSON(response.Status, response.JSON) + } + } +} diff --git a/internal/app/server/middleware/header.go b/internal/app/server/middleware/header.go new file mode 100644 index 0000000..accafb9 --- /dev/null +++ b/internal/app/server/middleware/header.go @@ -0,0 +1,22 @@ +package middleware + +import ( + "strings" + + "github.com/bastean/codexgo/v4/internal/pkg/service/env" + "github.com/gin-contrib/secure" + "github.com/gin-gonic/gin" +) + +func SecureHeaders() gin.HandlerFunc { + return secure.New(secure.Config{ + AllowedHosts: strings.Split(env.ServerGinAllowedHosts, ","), + STSSeconds: 315360000, + STSIncludeSubdomains: true, + FrameDeny: true, + ContentTypeNosniff: true, + BrowserXssFilter: true, + IENoOpen: true, + ReferrerPolicy: "strict-origin-when-cross-origin", + }) +} diff --git a/internal/app/server/middleware/limiter.go b/internal/app/server/middleware/limiter.go new file mode 100644 index 0000000..50e7b86 --- /dev/null +++ b/internal/app/server/middleware/limiter.go @@ -0,0 +1,28 @@ +package middleware + +import ( + "net/http" + "time" + + ratelimit "github.com/JGLTechnologies/gin-rate-limit" + "github.com/gin-gonic/gin" +) + +func RateLimiter() gin.HandlerFunc { + return ratelimit.RateLimiter( + ratelimit.InMemoryStore( + &ratelimit.InMemoryOptions{ + Rate: time.Second, + Limit: 10, + }, + ), + &ratelimit.Options{ + ErrorHandler: func(c *gin.Context, info ratelimit.Info) { + c.Status(http.StatusTooManyRequests) + }, + KeyFunc: func(c *gin.Context) string { + return c.ClientIP() + }, + }, + ) +} diff --git a/internal/app/server/middleware/recover.go b/internal/app/server/middleware/recover.go new file mode 100644 index 0000000..9ba5be0 --- /dev/null +++ b/internal/app/server/middleware/recover.go @@ -0,0 +1,30 @@ +package middleware + +import ( + "net/http" + + "github.com/bastean/codexgo/v4/internal/app/server/util/reply" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/logger/log" + "github.com/gin-gonic/gin" +) + +func Recover() gin.RecoveryFunc { + return func(c *gin.Context, err any) { + failure, ok := err.(error) + + if !ok { + failure = errors.NewInternal(&errors.Bubble{ + Where: "Recover", + What: "Unknown Error", + Why: errors.Meta{ + "Error": err, + }, + }) + } + + log.Error(failure.Error()) + + c.AbortWithStatusJSON(http.StatusInternalServerError, &reply.JSON{Message: "Server error. Try again later."}) + } +} diff --git a/internal/app/server/package.json b/internal/app/server/package.json new file mode 100644 index 0000000..6d46429 --- /dev/null +++ b/internal/app/server/package.json @@ -0,0 +1,7 @@ +{ + "devDependencies": { + "fomantic-ui": "2.9.3", + "jquery": "3.7.1", + "lodash": "4.17.21" + } +} diff --git a/internal/app/server/router/api/api.go b/internal/app/server/router/api/api.go new file mode 100644 index 0000000..a113c4f --- /dev/null +++ b/internal/app/server/router/api/api.go @@ -0,0 +1,41 @@ +package api + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/handler/user" + "github.com/bastean/codexgo/v4/internal/app/server/middleware" + "github.com/gin-gonic/gin" +) + +type API struct { + *gin.RouterGroup +} + +func (api *API) Public() { + public := api.Group("/") + + account := public.Group("/account") + + account.PUT("/", user.Create) + account.POST("/", user.Login) + + account.GET("/verify/:id", user.Verify) +} + +func (api *API) Private() { + private := api.Group("/", middleware.Authentication) + + account := private.Group("/account") + + account.PATCH("/", user.Update) + account.DELETE("/", user.Delete) +} + +func Use(group *gin.RouterGroup) { + api := &API{ + RouterGroup: group, + } + + api.Public() + + api.Private() +} diff --git a/internal/app/server/router/router.go b/internal/app/server/router/router.go new file mode 100644 index 0000000..1b3b541 --- /dev/null +++ b/internal/app/server/router/router.go @@ -0,0 +1,50 @@ +package router + +import ( + "embed" + "net/http" + + "github.com/bastean/codexgo/v4/internal/app/server/handler/health" + "github.com/bastean/codexgo/v4/internal/app/server/handler/redirect" + "github.com/bastean/codexgo/v4/internal/app/server/middleware" + "github.com/bastean/codexgo/v4/internal/app/server/router/api" + "github.com/bastean/codexgo/v4/internal/app/server/router/view" + "github.com/bastean/codexgo/v4/internal/pkg/service/env" + "github.com/gin-gonic/gin" +) + +var ( + Router *gin.Engine +) + +func New(files *embed.FS) *gin.Engine { + gin.SetMode(env.ServerGinMode) + + Router = gin.Default() + + Router.Use(gin.CustomRecovery(middleware.Recover())) + + Router.Use(middleware.ErrorHandler()) + + Router.Use(middleware.SecureHeaders()) + + Router.Use(middleware.RateLimiter()) + + Router.Use(middleware.CookieSession()) + + fs := http.FS(files) + + Router.StaticFS("/public", fs) + + Router.StaticFileFS("/robots.txt", "static/robots.txt", fs) + + api.Use(Router.Group("/v4")) + + view.Use(Router) + + Router.HEAD("/health", health.Check) + + Router.NoRoute(redirect.Default) + + return Router +} diff --git a/internal/app/server/router/view/view.go b/internal/app/server/router/view/view.go new file mode 100644 index 0000000..55f5547 --- /dev/null +++ b/internal/app/server/router/view/view.go @@ -0,0 +1,37 @@ +package view + +import ( + "github.com/bastean/codexgo/v4/internal/app/server/handler/page" + "github.com/bastean/codexgo/v4/internal/app/server/middleware" + "github.com/gin-gonic/gin" +) + +type View struct { + *gin.Engine +} + +func (view *View) Public() { + public := view.Group("/") + + home := public.Group("/") + + home.GET("/", page.Home) +} + +func (view *View) Private() { + private := view.Group("/", middleware.Authentication) + + dashboard := private.Group("/dashboard") + + dashboard.GET("/", page.Dashboard) +} + +func Use(router *gin.Engine) { + view := &View{ + Engine: router, + } + + view.Public() + + view.Private() +} diff --git a/internal/app/server/server.go b/internal/app/server/server.go new file mode 100644 index 0000000..1633780 --- /dev/null +++ b/internal/app/server/server.go @@ -0,0 +1,73 @@ +package server + +import ( + "context" + "embed" + "fmt" + "net/http" + "strings" + + "github.com/bastean/codexgo/v4/internal/app/server/router" + "github.com/bastean/codexgo/v4/internal/pkg/service/env" + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/bastean/codexgo/v4/internal/pkg/service/logger/log" +) + +var Server = &struct { + Gin string +}{ + Gin: log.Server("Gin"), +} + +var ( + //go:embed static + Files embed.FS + App *http.Server +) + +func Up() error { + log.Starting(Server.Gin) + + App = &http.Server{ + Addr: ":" + env.ServerGinPort, + Handler: router.New(&Files), + } + + log.Started(Server.Gin) + + log.Info(fmt.Sprintf("%s listening on %s", Server.Gin, env.ServerGinURL)) + + if proxy, ok := env.HasServerGinProxy(); ok { + log.Info(fmt.Sprintf("%s proxy listening on %s", Server.Gin, strings.Replace(env.ServerGinURL, env.ServerGinPort, proxy, 1))) + } + + if err := App.ListenAndServe(); errors.IsNot(err, http.ErrServerClosed) { + log.CannotBeStarted(Server.Gin) + + return errors.NewInternal(&errors.Bubble{ + Where: "Up", + What: "Failure to start Server", + Who: err, + }) + } + + return nil +} + +func Down(ctx context.Context) error { + log.Stopping(Server.Gin) + + if err := App.Shutdown(ctx); err != nil { + log.CannotBeStopped(Server.Gin) + + return errors.NewInternal(&errors.Bubble{ + Where: "Down", + What: "Failure to shutdown Server", + Who: err, + }) + } + + log.Stopped(Server.Gin) + + return nil +} diff --git a/internal/app/server/server_test.go b/internal/app/server/server_test.go new file mode 100644 index 0000000..3c3173b --- /dev/null +++ b/internal/app/server/server_test.go @@ -0,0 +1,159 @@ +package server_test + +import ( + "context" + "fmt" + "os" + "strings" + "testing" + "time" + + "github.com/bastean/codexgo/v4/internal/pkg/service/errors" + "github.com/cucumber/godog" + "github.com/playwright-community/playwright-go" + testify "github.com/stretchr/testify/assert" +) + +var ( + sut = os.Getenv("SUT_URL") +) + +var ( + pw *playwright.Playwright + browser playwright.Browser + browserCtx playwright.BrowserContext + page playwright.Page + element playwright.Locator +) + +var ( + headless = true + timeout float64 = 10000 + exact = true + sleep = 4 * time.Second +) + +var ( + err error + assert *testify.Assertions + expected, actual string +) + +func SetupAssert(t *testing.T) { + assert = testify.New(t) +} + +func SetupPlaywright() { + pw, err = playwright.Run() + + if err != nil { + errors.Panic(err.Error(), "SetupPlaywright") + } + + browser, err = pw.Chromium.Launch(playwright.BrowserTypeLaunchOptions{ + Headless: &headless, + Timeout: &timeout, + }) + + if err != nil { + errors.Panic(err.Error(), "SetupPlaywright") + } + + browserCtx, err = browser.NewContext(playwright.BrowserNewContextOptions{BaseURL: &sut}) + + if err != nil { + errors.Panic(err.Error(), "SetupPlaywright") + } + + page, err = browserCtx.NewPage() + + if err != nil { + errors.Panic(err.Error(), "SetupPlaywright") + } +} + +func SetupScenario(sc *godog.ScenarioContext) { + sc.Before(func(ctx context.Context, sc *godog.Scenario) (context.Context, error) { + //? browserCtx.ClearCookies() + return ctx, nil + }) + + sc.Given(`^I am on (.+) page$`, func(route string) { + _, err = page.Goto(route) + assert.NoError(err) + }) + + sc.Then(`^redirect me to (.+) page$`, func(actual string) { + time.Sleep(sleep) + + if actual == "/" { + actual = "" + } + + expected = page.URL() + + assert.True(strings.Contains(expected, actual)) + }) + + sc.Then(`^the page title should be (.+)$`, func(expected string) { + actual, err = page.Title() + + assert.NoError(err) + + assert.Equal(expected, actual) + }) + + sc.Then(`^I click on the (.+) button$`, func(name string) { + element = page.GetByText(name, playwright.PageGetByTextOptions{Exact: &exact}).First() + assert.NoError(element.Click()) + }) + + sc.Then(`^I open the (.+) menu$`, func(name string) { + element = page.GetByRole("heading").First() + assert.NoError(element.Click()) + }) + + sc.Then(`^I fill the (.+) with (.+)$`, func(placeholder, value string) { + element = page.GetByRole("textbox", playwright.PageGetByRoleOptions{Name: placeholder, Exact: &exact}).Last() + assert.NoError(element.Fill(value)) + }) + + sc.Then(`^I click the (.+) button$`, func(name string) { + element = page.GetByRole("button", playwright.PageGetByRoleOptions{Name: name}) + assert.NoError(element.Click()) + }) + + sc.Then(`^I check the (.+)$`, func(name string) { + element = page.GetByRole("checkbox") + assert.NoError(element.Check()) + }) + + sc.Then(`^I see (.+) notification$`, func(expected string) { + element = page.GetByRole("alert") + + actual, err = element.InnerText() + + assert.NoError(err) + + assert.Equal(expected, actual) + }) +} + +func TestAcceptanceServerFeatures(t *testing.T) { + SetupAssert(t) + + SetupPlaywright() + + suite := godog.TestSuite{ + ScenarioInitializer: SetupScenario, + Options: &godog.Options{ + Format: "pretty", + Paths: []string{"features"}, + TestingT: t, + }, + } + + if status := suite.Run(); status != 0 { + errors.Panic(fmt.Sprintf("Failure to run feature tests resulted in a non-zero status [%d]", status), "TestAcceptanceServerFeatures") + } +} diff --git a/internal/app/server/static/assets/apple-touch-icon.png b/internal/app/server/static/assets/apple-touch-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..26001cab756a813daa0b599b83aafb95d22dd6df GIT binary patch literal 1716 zcmV;l221&gP)DRK?CtIA?Cjp(;NIWg(bCex z#KptJ#KOeHwzs#nwzpl$;i##pr>Ut~zt&m5)mgsPnw*?gw8~br$yKzmEOj9pQQ#(CBJ3T%tLP#q@M=L={D?vvnH#{geJ0~|hCpSAMHajgZ zF(fT8BrGr_EH8u9W?BFM1zkx*K~#9!?c9A=+cp#i@JAcn*6!I7niopfHUT=9V!Tq) zQcBvH(l!ZUalZeznThP!mSq$|M%i|Me{tk1>FO;pM+fkKLL$ZviW-c8m$I@5YhW9| zkN_AUMcfB5OrlB55nvx62}Ff*1)68Na>NG!Isc8JNpc;ANuvQ^ZS5h_<}Lt|TZo0WE}CrNqf*fA8>v`xA|ojM%vnJr zlV^hkD>T?nCNei!gY-vOzZG94PyGSsLXXuMDFAy+0Zff6zNM7{5R_jv;Ls;~NOZXk zA%qY@2qBgb)tGr_FFwc88Z_ZjjfNJM@{(mfut|$(`Sc${np~k*gUjoA)B_a* zynMwDQ?*iioLPqxV+X*QQtB;$d_y!LXUG}2?Im&F0mTl6G#S;55jX~68+rfu__)qY z2XjaBF5UL?krQeMD2!sGcqaPPP8ZET06wX=+5Rw%5z=De^yiysW`hQuXOo8U;_1(* z*q_jvX6t5geGDOl5JCtcgb+dqA%wV7!Ww5hd+{M|W}lgsy?6)9i&!+U7oTHELz?=C zeI{4a!;ocF#Y>?@Me+Jg?zq}h0H>S@04BOq0PmTImY<+8v@Mcfvf?SUW|9RQI*mqS z6EmOIV)Fq^F?WF&HOx`F#`TSgeM~F%(o@lY_fcD~NYg)0t_w7SyWJ};ySU)4#j(w79S(IC&Fw~HVR)5@| zH-C~9ABBfCCdSvfYrLm0Q)gKlpoO>a0*ryDO8tx(mf4Hji!VUoCUZhV-F{2^_<9TQ zR>h#Pz=yT?0~T?RZH1qdQr|;+Z+!lgi+$YC)UT7=J}nhLBHR8HLI@#*5JCtcgb+dq zA%qY@2qAUML1>R1l)A54-08Zonq3^}~!!W|P7VXzq(t3BD=uU`lC2X*g zcMiirjg|Is`-Ypm+Il}9-Qd+)=eRvOA-DB3sn0dKZAQ2?QG*NFF$U}K4!7ipCGFka zV7FVh{a37gOZ4{c?)D>=1h@@mM)e+Y22G>fGjjicoY&uC1P9D}JcTJ}lJx+vXScPdu<(pib3+{_21qDTrurj$-EP+@2eVC9SO!)*GsE&GNY z(kZ|qD-dBNI>qnOGy9QS$K0e&mnW#OVJ_-Q7hw-Yy{btK=+c9gxAGmNZDfm(H(}l$ zEVfwT!1+?;VP!f@jO|O19dyG>*DGgr`s`v=K3_2<9Txo-R{z4%9-Gl#79EzJVO6$@ z)Bi?2w>@?1=Em#R!-@=<*uu<@mtSLlm0rQzzPL`e@t(0FUa|i-N_%c>Bc~H2CQUlE z$N$vy literal 0 HcmV?d00001 diff --git a/internal/app/server/static/assets/favicon.png b/internal/app/server/static/assets/favicon.png new file mode 100644 index 0000000000000000000000000000000000000000..26001cab756a813daa0b599b83aafb95d22dd6df GIT binary patch literal 1716 zcmV;l221&gP)DRK?CtIA?Cjp(;NIWg(bCex z#KptJ#KOeHwzs#nwzpl$;i##pr>Ut~zt&m5)mgsPnw*?gw8~br$yKzmEOj9pQQ#(CBJ3T%tLP#q@M=L={D?vvnH#{geJ0~|hCpSAMHajgZ zF(fT8BrGr_EH8u9W?BFM1zkx*K~#9!?c9A=+cp#i@JAcn*6!I7niopfHUT=9V!Tq) zQcBvH(l!ZUalZeznThP!mSq$|M%i|Me{tk1>FO;pM+fkKLL$ZviW-c8m$I@5YhW9| zkN_AUMcfB5OrlB55nvx62}Ff*1)68Na>NG!Isc8JNpc;ANuvQ^ZS5h_<}Lt|TZo0WE}CrNqf*fA8>v`xA|ojM%vnJr zlV^hkD>T?nCNei!gY-vOzZG94PyGSsLXXuMDFAy+0Zff6zNM7{5R_jv;Ls;~NOZXk zA%qY@2qBgb)tGr_FFwc88Z_ZjjfNJM@{(mfut|$(`Sc${np~k*gUjoA)B_a* zynMwDQ?*iioLPqxV+X*QQtB;$d_y!LXUG}2?Im&F0mTl6G#S;55jX~68+rfu__)qY z2XjaBF5UL?krQeMD2!sGcqaPPP8ZET06wX=+5Rw%5z=De^yiysW`hQuXOo8U;_1(* z*q_jvX6t5geGDOl5JCtcgb+dqA%wV7!Ww5hd+{M|W}lgsy?6)9i&!+U7oTHELz?=C zeI{4a!;ocF#Y>?@Me+Jg?zq}h0H>S@04BOq0PmTImY<+8v@Mcfvf?SUW|9RQI*mqS z6EmOIV)Fq^F?WF&HOx`F#`TSgeM~F%(o@lY_fcD~NYg)0t_w7SyWJ};ySU)4#j(w79S(IC&Fw~HVR)5@| zH-C~9ABBfCCdSvfYrLm0Q)gKlpoO>a0*ryDO8tx(mf4Hji!VUoCUZhV-F{2^_<9TQ zR>h#Pz=yT?0~T?RZH1qdQr|;+Z+!lgi+$YC)UT7=J}nhLBHR8HLI@#*5JCtcgb+dq zA%qY@2qAUML1>R1l)A54-08Zonq3^}~!!W|P7VXzq(t3BD=uU`lC2X*g zcMiirjg|Is`-Ypm+Il}9-Qd+)=eRvOA-DB3sn0dKZAQ2?QG*NFF$U}K4!7ipCGFka zV7FVh{a37gOZ4{c?)D>=1h@@mM)e+Y22G>fGjjicoY&uC1P9D}JcTJ}lJx+vXScPdu<(pib3+{_21qDTrurj$-EP+@2eVC9SO!)*GsE&GNY z(kZ|qD-dBNI>qnOGy9QS$K0e&mnW#OVJ_-Q7hw-Yy{btK=+c9gxAGmNZDfm(H(}l$ zEVfwT!1+?;VP!f@jO|O19dyG>*DGgr`s`v=K3_2<9Txo-R{z4%9-Gl#79EzJVO6$@ z)Bi?2w>@?1=Em#R!-@=<*uu<@mtSLlm0rQzzPL`e@t(0FUa|i-N_%c>Bc~H2CQUlE z$N$vy literal 0 HcmV?d00001 diff --git a/internal/app/server/static/assets/logo.png b/internal/app/server/static/assets/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..52ba8b9d21f0e60ba34dec197e2a6451c01307a6 GIT binary patch literal 4820 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.title,.ui.accordion.menu .item>.title,.ui.accordion>.title{cursor:pointer;padding:.5em 0;font-family:Lato,system-ui,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";font-size:1em;color:rgba(0,0,0,.87);list-style:none;line-height:1}.ui.accordion:not(.styled) .accordion .title~.content,.ui.accordion:not(.styled) .title~.content{margin:"";padding:.5em 0 1em}.ui.accordion:not(.styled) .title~.content:last-child{padding-bottom:0}.ui.accordion .accordion .title>.dropdown.icon,.ui.accordion .title>.dropdown.icon,.ui.accordion .ui.header>.dropdown.icon{display:inline-block;float:none;opacity:1;width:1.25em;height:1em;margin:0 .25rem 0 0;padding:0;font-size:1em;transition:transform .1s ease,opacity .1s ease;vertical-align:baseline;transform:none}.ui.accordion .accordion .title>.dropdown.icon.right,.ui.accordion .title>.dropdown.icon.right,.ui.accordion .ui.header>.dropdown.icon.right{float:right;transform:rotate(180deg)}.ui.accordion.menu .item .title{display:block;padding:0}.ui.accordion.menu .item .title>.dropdown.icon{float:right;margin:0 .25rem 0 0;transform:rotate(180deg)}.ui.accordion .ui.header>.dropdown.icon{font-size:1em;margin:0 .25rem 0 0}.ui.accordion .accordion .active.title>.dropdown.icon,.ui.accordion .accordion[open]>.title>.dropdown.icon,.ui.accordion .active.title>.dropdown.icon,.ui.accordion[open]>.title>.dropdown.icon{transform:rotate(90deg)}.ui.accordion.menu .item .active.title>.dropdown.icon{transform:rotate(90deg)}.ui.styled.accordion{width:600px}.ui.styled.accordion,.ui.styled.accordion .accordion{border-radius:.28571429rem;background:#fff;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15)}.ui.styled.accordion .accordion>.title,.ui.styled.accordion>.title{margin:0;padding:.75em 1em;color:rgba(0,0,0,.4);font-weight:700;border-top:1px solid rgba(34,36,38,.15);transition:background .1s ease,color .1s ease}.ui.styled.accordion .accordion>.title:first-child,.ui.styled.accordion>.title:first-child{border-top:none}.ui.styled.accordion>.content{margin:0;padding:.5em 1em 1.5em}.ui.styled.accordion .accordion>.content{margin:0;padding:.5em 1em 1.5em}.ui.styled.accordion>.title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .accordion>.title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.styled.accordion .active.title,.ui.styled.accordion[open]>.title{background:0 0;color:rgba(0,0,0,.95)}.ui.styled.accordion .accordion .active.title,.ui.styled.accordion .accordion[open]>.title{background:0 0;color:rgba(0,0,0,.95)}.ui.compact.accordion:not(.styled) .accordion>.title,.ui.compact.accordion:not(.styled)>.title{padding:.25em 0}.ui.compact.accordion:not(.styled) .accordion .title~.content,.ui.compact.accordion:not(.styled) .title~.content{padding:.25em 0 .5em}.ui.compact.styled.accordion .accordion>.title,.ui.compact.styled.accordion>.title{padding:.375em .5em}.ui.compact.styled.accordion .accordion .title~.content,.ui.compact.styled.accordion .title~.content{padding:.25em .5em .75em}.ui[class*="very compact"].accordion:not(.styled) .accordion>.title,.ui[class*="very compact"].accordion:not(.styled)>.title{padding:.125em 0}.ui[class*="very compact"].accordion:not(.styled) .accordion .title~.content,.ui[class*="very compact"].accordion:not(.styled) .title~.content{padding:.125em 0 .25em}.ui[class*="very compact"].styled.accordion .accordion>.title,.ui[class*="very compact"].styled.accordion>.title{padding:.1875em .25em}.ui[class*="very compact"].styled.accordion .accordion .title~.content,.ui[class*="very compact"].styled.accordion .title~.content{padding:.125em .25em .375em}.ui.accordion .accordion:not(details) .title~.content:not(.active),.ui.accordion:not(details) .title~.content:not(.active){display:none}.ui.fluid.accordion,.ui.fluid.accordion .accordion{width:100%}.ui.inverted.accordion .accordion>.title,.ui.inverted.accordion.menu .item>.title,.ui.inverted.accordion>.title{color:rgba(255,255,255,.9)}.ui.inverted.styled.accordion,.ui.inverted.styled.accordion .accordion{background:#1b1c1d;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(255,255,255,.1)}.ui.inverted.styled.accordion .accordion>.title,.ui.inverted.styled.accordion>.title{color:rgba(255,255,255,.5);border-top:1px solid rgba(255,255,255,.1)}.ui.inverted.styled.accordion>.title:hover{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.styled.accordion .accordion>.title:hover{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.styled.accordion .active.title,.ui.inverted.styled.accordion[open]>.title{background:0 0;color:#fff}.ui.inverted.styled.accordion .accordion .active.title,.ui.inverted.styled.accordion .accordion[open]>.title{background:0 0;color:#fff}.ui.basic.styled.accordion,.ui.basic.styled.accordion .accordion{background:0 0;box-shadow:none}.ui.basic.styled.accordion .accordion>.title,.ui.basic.styled.accordion>.title{border:none;color:rgba(0,0,0,.6)}.ui.basic.styled.accordion .accordion>.title:hover,.ui.basic.styled.accordion>.title:hover{background:0 0;color:rgba(0,0,0,.87)}.ui.basic.styled.accordion .accordion .active.title,.ui.basic.styled.accordion .accordion[open]>.title,.ui.basic.styled.accordion .active.title,.ui.basic.styled.accordion[open]>.title{background:0 0;color:rgba(0,0,0,.95)}.ui.inverted.basic.styled.accordion .accordion>.title,.ui.inverted.basic.styled.accordion>.title{background:0 0;color:rgba(255,255,255,.8)}.ui.inverted.basic.styled.accordion .accordion>.title:hover,.ui.inverted.basic.styled.accordion>.title:hover{background:0 0;color:rgba(255,255,255,.9)}.ui.inverted.basic.styled.accordion .accordion .active.title,.ui.inverted.basic.styled.accordion .accordion[open]>.title,.ui.inverted.basic.styled.accordion .active.title,.ui.inverted.basic.styled.accordion[open]>.title{background:0 0;color:#fff}.ui.tree.accordion:not(.styled) .accordion .title~.content,.ui.tree.accordion:not(.styled) .title~.content{padding:0}.ui.tree.accordion .accordion>.content,.ui.tree.accordion>.content{margin-left:1.7em}.ui.tree.accordion .accordion{margin-top:0}@font-face{font-family:Accordion;src:url(data:application/font-woff;base64,d09GRk9UVE8AAAREAAsAAAAABkAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAC7AAAAQoAAAE/j/fxwUZGVE0AAAQUAAAAHAAAAByNqvxQR0RFRgAAA/gAAAAcAAAAIAAnABhPUy8yAAABYAAAAEIAAABgTadW5mNtYXAAAAKMAAAAUQAAAWAFZuKDaGVhZAAAAQgAAAAyAAAANg8zT8toaGVhAAABPAAAABoAAAAkApkA5mhtdHgAAAQwAAAAEwAAABYBtwASbWF4cAAAAVgAAAAGAAAABgAGUABuYW1lAAABpAAAAOYAAAGq/HAhWXBvc3QAAALgAAAADAAAACAAAwAAeJxjYGRgYADi8KWRsvH8Nl8ZuJkYQOD838XvQPT9hGxNIOXJsJ0xD0hzMIClARzsCcoAAHicY2BkYGB88P8BkGQAg+0wBhywAgBgjgOAAAAAAFAAAAYAAHicY2BmOM84gYGVgYHRhzGNgYHBHUp/ZZBkaGFABYwCSJyANNcUBgcGhg+3GB/8fwCUfMCgAFIDV6AAhIwARVcMJwAAeJx1jrFOwzAURU/SNKgFIVgQ6uSRKWolZjaQOnQBqQNb2lpRpMqW3HTowhew8U9I/BU37WOjtmyfd/3utYEbvsn4G7lxRsmtcc4FD8YD6U/GhfjNeMglybjU/DQeM+FHrqwY2QsnzrgSnTjnmnvjgfSpcSF+Nh5yx7txKf3DeMwjX31soqajJdCoqLs26HzFq9yz1WVS6Zv9tk5nmv8Vl0pI7CRHXThmVPofS592bQxuVk3PGF+Ohk6WRhHhGNO3eTbSVhy0z1mra6HV91YyxdC5xgevFL9xq4Obr+MixlDxC/HTOrsAAHicY2BgYGaAYBkGRgYQiALyGMF8FgY7IM3FwMHABISMDAofbv3/+/8/WJXCh5tgNuP/x2A+RC8bUC0DUB8rWIgNiJkY8AJm/NJDHgAALqoOxgAAAHicY2BmwAsAAH0ABHicPY7BSsNAEIZnkk2zlhg1JKAYxOrJi6RepMdC8SKefAJP4kVBzCtkNw7ZjeK1j9C38Rn6CO5CDrppigwMM8P/f/8gMAaIGL4+vD09PwJ6gLCwp2AnaM88e+7bQ0aRTxE7GcPRffJL9D9EIX2bW+sFOXzu5QD7OSwPcuA5Xiew05N8CIDDLiSQuTqGSVmU0/KqKG+Kxaxv8+llMURvHwBAgRJrfEeCEaLns9HdRxzHP/FqaV4yaptWK25SkwZKu4Va0rUSWjYVVbz7CqmqhZBSiNodqGqk5l2vFqrW1PJ4tWbGqZxVKa31htA6gmN2aTBwBobzuYsU1YYkGheyZVBqLjKKxn8cSmvuAAB4nGNgZGBg4AFiAQYJBiYgzQLEIJoRggEFbQBAAAAAAQAAAADeTO04AAAAAM/9o+4AAAAA32BrKXicY2BAAEYQsZ1BiIEBAAPpAMsA) format("woff");font-weight:400;font-style:normal}.ui.accordion .accordion .title>.dropdown.icon,.ui.accordion .title>.dropdown.icon,.ui.accordion .ui.header>.dropdown.icon{font-family:Accordion;line-height:1;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.accordion .accordion .title>.dropdown.icon::before,.ui.accordion .title>.dropdown.icon::before,.ui.accordion .ui.header>.dropdown.icon::before{content:"\f0da"} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/accordion.min.js b/internal/app/server/static/dist/fomantic-ui.com/components/accordion.min.js new file mode 100755 index 0000000..b87eac6 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/accordion.min.js @@ -0,0 +1,11 @@ +/* + * # Fomantic UI - 2.9.3 + * https://github.com/fomantic/Fomantic-UI + * https://fomantic-ui.com/ + * + * Copyright 2023 Contributors + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */ +!function(O,x){"use strict";x=void 0!==x&&x.Math===Math?x:globalThis,O.fn.accordion=function(v){var p,e=O(this),m=Date.now(),h=[],b=v,y="string"==typeof b,C=[].slice.call(arguments,1);return e.each(function(){var e,a=O.isPlainObject(v)?O.extend(!0,{},O.fn.accordion.settings,v):O.extend({},O.fn.accordion.settings),s=a.className,n=a.namespace,l=a.selector,c=a.error,i="."+n,t="module-"+n,o=O(this),r=o.find(l.title),d=o.find(l.content),u=this,g=o.data(t),f={initialize:function(){f.debug("Initializing",o),f.bind.events(),a.observeChanges&&f.observeChanges(),f.instantiate()},instantiate:function(){g=f,o.data(t,f)},destroy:function(){f.debug("Destroying previous instance",o),o.off(i).removeData(t)},refresh:function(){r=o.find(l.title),d=o.find(l.content)},observeChanges:function(){"MutationObserver"in x&&((e=new MutationObserver(function(e){f.debug("DOM tree modified, updating selector cache"),f.refresh()})).observe(u,{childList:!0,subtree:!0}),f.debug("Setting up mutation observer",e))},bind:{events:function(){f.debug("Binding delegated events"),o.on(a.on+i,l.trigger,f.event.click)}},event:{click:function(e){0===O(e.target).closest(l.ignore).length&&f.toggle.call(this)}},toggle:function(e){var e=void 0!==e?"number"==typeof e?r.eq(e):O(e).closest(l.title):O(this).closest(l.title),n=e.next(d),i=n.hasClass(s.animating),n=n.hasClass(s.active),t=n&&!i,n=!n&&i;f.debug("Toggling visibility of content",e),t||n?a.collapsible?f.close.call(e):f.debug("Cannot close accordion content collapsing is disabled"):f.open.call(e)},open:function(e){var e=void 0!==e?"number"==typeof e?r.eq(e):O(e).closest(l.title):O(this).closest(l.title),n=e.next(d),i=n.hasClass(s.animating);n.hasClass(s.active)||i?f.debug("Accordion already open, skipping",n):(f.debug("Opening accordion content",e),a.onOpening.call(n),a.onChanging.call(n),a.exclusive&&f.closeOthers.call(e),e.addClass(s.active),n.stop(!0,!0).addClass(s.animating),a.animateChildren&&(void 0!==O.fn.transition?n.children().transition({animation:"fade in",queue:!1,useFailSafe:!0,debug:a.debug,verbose:a.verbose,silent:a.silent,duration:a.duration,skipInlineHidden:!0,onComplete:function(){n.children().removeClass(s.transition)}}):n.children().stop(!0,!0).animate({opacity:1},a.duration,f.resetOpacity)),n.slideDown(a.duration,a.easing,function(){n.removeClass(s.animating).addClass(s.active),f.reset.display.call(this),a.onOpen.call(this),a.onChange.call(this)}))},close:function(e){var e=void 0!==e?"number"==typeof e?r.eq(e):O(e).closest(l.title):O(this).closest(l.title),n=e.next(d),i=n.hasClass(s.animating),t=n.hasClass(s.active);!t&&!(!t&&i)||t&&i||(f.debug("Closing accordion content",n),a.onClosing.call(n),a.onChanging.call(n),e.removeClass(s.active),n.stop(!0,!0).addClass(s.animating),a.animateChildren&&(void 0!==O.fn.transition?n.children().transition({animation:"fade out",queue:!1,useFailSafe:!0,debug:a.debug,verbose:a.verbose,silent:a.silent,duration:a.duration,skipInlineHidden:!0}):n.children().stop(!0,!0).animate({opacity:0},a.duration,f.resetOpacity)),n.slideUp(a.duration,a.easing,function(){n.removeClass(s.animating).removeClass(s.active),f.reset.display.call(this),a.onClose.call(this),a.onChange.call(this)}))},closeOthers:function(e){var n,e=void 0!==e?r.eq(e):O(this).closest(l.title),i=e.parents(l.content).prev(l.title),e=e.closest(l.accordion),t=l.title+"."+s.active+":visible",o=l.content+"."+s.active+":visible",o=a.closeNested?(n=e.find(t).not(i)).next(d):(n=e.find(t).not(i),e=e.find(o).find(t).not(i),(n=n.not(e)).next(d));0.active.section{color:#fff}.ui.inverted.breadcrumb>.divider{color:rgba(255,255,255,.7)}.ui.breadcrumb .active.section{font-weight:700}.ui.breadcrumb{font-size:1rem}.ui.mini.breadcrumb{font-size:.78571429rem}.ui.tiny.breadcrumb{font-size:.85714286rem}.ui.small.breadcrumb{font-size:.92857143rem}.ui.large.breadcrumb{font-size:1.14285714rem}.ui.big.breadcrumb{font-size:1.28571429rem}.ui.huge.breadcrumb{font-size:1.42857143rem}.ui.massive.breadcrumb{font-size:1.71428571rem} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/button.min.css b/internal/app/server/static/dist/fomantic-ui.com/components/button.min.css new file mode 100755 index 0000000..291b06f --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/button.min.css @@ -0,0 +1,9 @@ +/*! + * # Fomantic-UI 2.9.3 - Button + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */.ui.button{cursor:pointer;display:inline-block;min-height:1em;outline:0;border:none;vertical-align:baseline;background:#e0e1e2 none;color:rgba(0,0,0,.6);font-family:Lato,system-ui,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";margin:0 .25em 0 0;padding:.78571429em 1.5em .78571429em;text-transform:none;text-shadow:none;font-weight:700;line-height:1em;font-style:normal;text-align:center;text-decoration:none;border-radius:.28571429rem;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;-webkit-user-select:none;-ms-user-select:none;user-select:none;transition:opacity .1s ease,background-color .1s ease,color .1s ease,box-shadow .1s ease,background .1s ease;will-change:auto;-webkit-tap-highlight-color:transparent}.ui.button:hover{background-color:#cacbcd;background-image:none;box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset;color:rgba(0,0,0,.8)}.ui.button:hover .icon{opacity:.85}.ui.button:focus{background-color:#cacbcd;color:rgba(0,0,0,.8);background-image:none;box-shadow:""}.ui.button:focus .icon{opacity:.85}.ui.active.button:active,.ui.button:active{background-color:#babbbc;background-image:"";color:rgba(0,0,0,.9);box-shadow:none}.ui.active.button{background-color:#c0c1c2;background-image:none;box-shadow:0 0 0 1px transparent inset;color:rgba(0,0,0,.95)}.ui.active.button:hover{background-color:#c0c1c2;background-image:none;color:rgba(0,0,0,.95)}.ui.active.button:active{background-color:#c0c1c2;background-image:none}.ui.ui.ui.ui.ui.ui.loading.button{position:relative;cursor:default;text-shadow:none!important;color:transparent;opacity:1;pointer-events:auto;transition:all 0s linear,opacity .1s ease}.ui.loading.button::before{position:absolute;content:"";top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.15)}.ui.loading.button::after{position:absolute;content:"";top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;animation:loader .6s infinite linear;border:.2em solid currentColor;color:#fff;box-shadow:0 0 0 1px transparent}.ui.ui.ui.loading.button .label{background-color:transparent;border-color:transparent;color:transparent}.ui.labeled.icon.loading.button .icon{background-color:transparent;box-shadow:none}.ui.basic.loading.button:not(.inverted)::before{border-color:rgba(0,0,0,.1)}.ui.basic.loading.button:not(.inverted)::after{border-color:#767676}.ui.button:disabled,.ui.buttons .disabled.button:not(.basic),.ui.disabled.active.button,.ui.disabled.button,.ui.disabled.button:hover{cursor:default;opacity:.45!important;background-image:none;box-shadow:none;pointer-events:none!important}.ui.basic.buttons .ui.disabled.button{border-color:rgba(34,36,38,.5)}.ui.animated.button{position:relative;overflow:hidden;padding-right:0!important;vertical-align:middle;z-index:1}.ui.animated.button .content{will-change:transform,opacity}.ui.animated.button .visible.content{position:relative;margin-right:1.5em}.ui.animated.button .hidden.content{position:absolute;width:100%}.ui.animated.button .hidden.content,.ui.animated.button .visible.content{transition:right .3s ease 0s}.ui.animated.button .visible.content{left:auto;right:0}.ui.animated.button .hidden.content{top:50%;left:auto;right:-100%;margin-top:-.5em}.ui.animated.button:focus .visible.content,.ui.animated.button:hover .visible.content{left:auto;right:200%}.ui.animated.button:focus .hidden.content,.ui.animated.button:hover .hidden.content{left:auto;right:0}.ui.vertical.animated.button .hidden.content,.ui.vertical.animated.button .visible.content{transition:top .3s ease,transform .3s ease}.ui.vertical.animated.button .visible.content{transform:translateY(0);right:auto}.ui.vertical.animated.button .hidden.content{top:-50%;left:0;right:auto}.ui.vertical.animated.button:focus .visible.content,.ui.vertical.animated.button:hover .visible.content{transform:translateY(200%);right:auto}.ui.vertical.animated.button:focus .hidden.content,.ui.vertical.animated.button:hover .hidden.content{top:50%;right:auto}.ui.fade.animated.button .hidden.content,.ui.fade.animated.button .visible.content{transition:opacity .3s ease,transform .3s ease}.ui.fade.animated.button .visible.content{left:auto;right:auto;opacity:1;transform:scale(1)}.ui.fade.animated.button .hidden.content{opacity:0;left:0;right:auto;transform:scale(1.5)}.ui.fade.animated.button:focus .visible.content,.ui.fade.animated.button:hover .visible.content{left:auto;right:auto;opacity:0;transform:scale(.75)}.ui.fade.animated.button:focus .hidden.content,.ui.fade.animated.button:hover .hidden.content{left:0;right:auto;opacity:1;transform:scale(1)}.ui.inverted.button{box-shadow:0 0 0 2px #fff inset;background:transparent none;color:#fff;text-shadow:none!important}.ui.inverted.buttons .button{margin:0 0 0 -2px}.ui.inverted.buttons .button:first-child{margin-left:0}.ui.inverted.vertical.buttons .button{margin:0 0 -2px 0}.ui.inverted.vertical.buttons .button:first-child{margin-top:0}.ui.inverted.button:hover{background:#fff;box-shadow:0 0 0 2px #fff inset;color:rgba(0,0,0,.8)}.ui.inverted.button.active,.ui.inverted.button:focus{background:#fff;box-shadow:0 0 0 2px #fff inset;color:rgba(0,0,0,.8)}.ui.inverted.button.active:focus{background:#dcddde;box-shadow:0 0 0 2px #dcddde inset;color:rgba(0,0,0,.8)}.ui.labeled.button:not(.icon){display:inline-flex;flex-direction:row;background:0 0;padding:0!important;border:none;box-shadow:none}.ui.labeled.button>.button{margin:0}.ui.labeled.button>.label{display:flex;align-items:center;margin:0 0 0 -1px!important;font-size:1em;padding:"";border-color:rgba(34,36,38,.15)}.ui.labeled.button>.tag.label::before{width:1.85em;height:1.85em}.ui.labeled.button:not([class*="left labeled"])>.button{border-top-right-radius:0;border-bottom-right-radius:0}.ui.labeled.button:not([class*="left labeled"])>.label{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*="left labeled"].button>.button{border-top-left-radius:0;border-bottom-left-radius:0}.ui[class*="left labeled"].button>.label{border-top-right-radius:0;border-bottom-right-radius:0}.ui.facebook.button{background-color:#3b5998;color:#fff;text-shadow:none;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.facebook.button:hover{background-color:#304d8a;color:#fff;text-shadow:none}.ui.facebook.button:active{background-color:#2d4373;color:#fff;text-shadow:none}.ui.twitter.button{background-color:#1da1f2;color:#fff;text-shadow:none;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.twitter.button:hover{background-color:#0298f3;color:#fff;text-shadow:none}.ui.twitter.button:active{background-color:#0c85d0;color:#fff;text-shadow:none}.ui.google.plus.button{background-color:#dd4b39;color:#fff;text-shadow:none;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.google.plus.button:hover{background-color:#e0321c;color:#fff;text-shadow:none}.ui.google.plus.button:active{background-color:#c23321;color:#fff;text-shadow:none}.ui.linkedin.button{background-color:#0077b5;color:#fff;text-shadow:none}.ui.linkedin.button:hover{background-color:#00669c;color:#fff;text-shadow:none}.ui.linkedin.button:active{background-color:#005582;color:#fff;text-shadow:none}.ui.youtube.button{background-color:red;color:#fff;text-shadow:none;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.youtube.button:hover{background-color:#e60000;color:#fff;text-shadow:none}.ui.youtube.button:active{background-color:#c00;color:#fff;text-shadow:none}.ui.instagram.button{background-color:#49769c;color:#fff;text-shadow:none;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.instagram.button:hover{background-color:#3d698e;color:#fff;text-shadow:none}.ui.instagram.button:active{background-color:#395c79;color:#fff;text-shadow:none}.ui.pinterest.button{background-color:#bd081c;color:#fff;text-shadow:none;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.pinterest.button:hover{background-color:#ac0013;color:#fff;text-shadow:none}.ui.pinterest.button:active{background-color:#8c0615;color:#fff;text-shadow:none}.ui.vk.button{background-color:#45668e;color:#fff;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.vk.button:hover{background-color:#395980;color:#fff}.ui.vk.button:active{background-color:#344d6c;color:#fff}.ui.whatsapp.button{background-color:#25d366;color:#fff;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.whatsapp.button:hover{background-color:#19c55a;color:#fff}.ui.whatsapp.button:active{background-color:#1da851;color:#fff}.ui.telegram.button{background-color:#08c;color:#fff;background-image:none;box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.telegram.button:hover{background-color:#0077b3;color:#fff}.ui.telegram.button:active{background-color:#069;color:#fff}.ui.button>.icon:not(.button){height:auto;opacity:.8;transition:opacity .1s ease;color:""}.ui.button:not(.icon)>.icon:not(.button):not(.dropdown),.ui.button:not(.icon)>.icons:not(.button):not(.dropdown){margin:0 .42857143em 0 -.21428571em;vertical-align:baseline}.ui.button:not(.icon)>.icons:not(.button):not(.dropdown)>.icon{vertical-align:baseline}.ui.button:not(.icon)>.right.icon:not(.button):not(.dropdown){margin:0 -.21428571em 0 .42857143em}@media only screen and (max-width:767.98px){.ui.stackable.buttons{flex-direction:column;width:100%}.ui.stackable.buttons .button:first-child{border-bottom-left-radius:0;border-top-right-radius:.28571429rem}.ui.stackable.buttons .button:last-child{border-bottom-left-radius:.28571429rem;border-top-right-radius:0}.ui.stackable.buttons .button:only-child{border-radius:.28571429rem}}.ui[class*="left floated"].button,.ui[class*="left floated"].buttons{float:left;margin-left:0;margin-right:.25em}.ui[class*="right floated"].button,.ui[class*="right floated"].buttons{float:right;margin-right:0;margin-left:.25em}.ui.compact.button,.ui.compact.buttons .button{padding:.58928571em 1.125em .58928571em}.ui.compact.icon.button,.ui.compact.icon.buttons .button{padding:.58928571em .58928571em .58928571em}.ui.compact.labeled.icon.button,.ui.compact.labeled.icon.buttons .button{padding:.58928571em 3.69642857em .58928571em}.ui.compact.labeled.icon.button>.icon,.ui.compact.labeled.icon.buttons .button>.icon{padding:.58928571em 0}.ui.button,.ui.buttons .button,.ui.buttons .or{font-size:1rem}.ui.mini.buttons .button,.ui.mini.buttons .dropdown,.ui.mini.buttons .dropdown .menu>.item,.ui.mini.buttons .or,.ui.ui.ui.ui.mini.button{font-size:.78571429rem}.ui.tiny.buttons .button,.ui.tiny.buttons .dropdown,.ui.tiny.buttons .dropdown .menu>.item,.ui.tiny.buttons .or,.ui.ui.ui.ui.tiny.button{font-size:.85714286rem}.ui.small.buttons .button,.ui.small.buttons .dropdown,.ui.small.buttons .dropdown .menu>.item,.ui.small.buttons .or,.ui.ui.ui.ui.small.button{font-size:.92857143rem}.ui.large.buttons .button,.ui.large.buttons .dropdown,.ui.large.buttons .dropdown .menu>.item,.ui.large.buttons .or,.ui.ui.ui.ui.large.button{font-size:1.14285714rem}.ui.big.buttons .button,.ui.big.buttons .dropdown,.ui.big.buttons .dropdown .menu>.item,.ui.big.buttons .or,.ui.ui.ui.ui.big.button{font-size:1.28571429rem}.ui.huge.buttons .button,.ui.huge.buttons .dropdown,.ui.huge.buttons .dropdown .menu>.item,.ui.huge.buttons .or,.ui.ui.ui.ui.huge.button{font-size:1.42857143rem}.ui.massive.buttons .button,.ui.massive.buttons .dropdown,.ui.massive.buttons .dropdown .menu>.item,.ui.massive.buttons .or,.ui.ui.ui.ui.massive.button{font-size:1.71428571rem}.ui.icon.button:not(.animated):not(.compact):not(.labeled),.ui.icon.buttons .button{padding:.78571429em .78571429em .78571429em}.ui.animated.icon.button>.content>.icon,.ui.icon.button>.icon,.ui.icon.buttons .button>.icon{opacity:.9;margin:0!important;vertical-align:top}.ui.animated.button>.content>.icon{vertical-align:top}.ui.basic.button,.ui.basic.buttons .button{background:transparent none;color:rgba(0,0,0,.6);font-weight:400;border-radius:.28571429rem;text-transform:none;text-shadow:none!important;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset}.ui.basic.buttons{box-shadow:none;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;border-right:none}.ui.basic.buttons .button{border-radius:0}.ui.basic.button:hover,.ui.basic.buttons .button:hover{background:#fff;color:rgba(0,0,0,.8);box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.basic.button:focus,.ui.basic.buttons .button:focus{background:#fff;color:rgba(0,0,0,.8);box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.basic.button:active,.ui.basic.buttons .button:active{background:#f8f8f8;color:rgba(0,0,0,.9);box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset}.ui.basic.active.button,.ui.basic.buttons .active.button{background:rgba(0,0,0,.05);box-shadow:"";color:rgba(0,0,0,.95)}.ui.basic.active.button:hover,.ui.basic.buttons .active.button:hover{background-color:rgba(0,0,0,.05)}.ui.basic.buttons .button:hover{box-shadow:0 0 0 1px rgba(34,36,38,.35) inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.basic.buttons .button:active{box-shadow:0 0 0 1px rgba(0,0,0,.15) inset,0 1px 4px 0 rgba(34,36,38,.15) inset}.ui.basic.buttons .active.button{box-shadow:""}.ui.basic.inverted.button,.ui.basic.inverted.buttons .button{background-color:transparent;color:#f9fafb;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset}.ui.basic.inverted.button:hover,.ui.basic.inverted.buttons .button:hover{color:#fff;box-shadow:0 0 0 2px #fff inset}.ui.basic.inverted.button:focus,.ui.basic.inverted.buttons .button:focus{color:#fff;box-shadow:0 0 0 2px #fff inset}.ui.basic.inverted.button:active,.ui.basic.inverted.buttons .button:active{background-color:rgba(255,255,255,.08);color:#fff;box-shadow:0 0 0 2px rgba(255,255,255,.9) inset}.ui.basic.inverted.active.button,.ui.basic.inverted.buttons .active.button{background-color:rgba(255,255,255,.08);color:#fff;text-shadow:none;box-shadow:0 0 0 2px rgba(255,255,255,.7) inset}.ui.basic.inverted.active.button:hover,.ui.basic.inverted.buttons .active.button:hover{background-color:rgba(255,255,255,.15);box-shadow:0 0 0 2px #fff inset}.ui.basic.buttons:not(.inverted) .button:not(.basic){border-right:1px solid rgba(34,36,38,.15);box-shadow:none}.ui.basic.vertical.buttons .button{border-left:none;border-left-width:0;border-top:1px solid rgba(34,36,38,.15)}.ui.basic.vertical.buttons:not(.spaced) .button:first-child{border-top:none}.ui.tertiary.button{transition:color .1s ease!important;border-radius:0;margin:.28571429em .25em .28571429em 0!important;padding:.5em .5em!important;box-shadow:none;color:rgba(0,0,0,.6);background:0 0}.ui.tertiary.button:hover{box-shadow:inset 0 -.2em 0 #666;color:#333;background:0 0}.ui.tertiary.button:focus{box-shadow:inset 0 -.2em 0 #666;color:#333;background:0 0}.ui.tertiary.button:active{box-shadow:inset 0 -.2em 0 #999;border-radius:.28571429rem .28571429rem 0 0;color:#666;background:0 0}.ui.labeled.icon.button,.ui.labeled.icon.buttons .button{position:relative;padding-left:4.07142857em!important;padding-right:1.5em!important}.ui.labeled.icon.button>.icon,.ui.labeled.icon.buttons>.button>.icon{position:absolute;top:0;left:0;height:100%;line-height:1;border-radius:0;border-top-left-radius:inherit;border-bottom-left-radius:inherit;text-align:center;animation:none;padding:.78571429em 0;margin:0;width:2.57142857em;background-color:rgba(0,0,0,.05);color:"";box-shadow:-1px 0 0 0 transparent inset}.ui[class*="right labeled"].icon.button{padding-right:4.07142857em!important;padding-left:1.5em!important}.ui[class*="right labeled"].icon.button>.icon{left:auto;right:0;border-radius:0;border-top-right-radius:inherit;border-bottom-right-radius:inherit;box-shadow:1px 0 0 0 transparent inset}.ui.labeled.icon.button>.icon::after,.ui.labeled.icon.button>.icon::before,.ui.labeled.icon.buttons>.button>.icon::after,.ui.labeled.icon.buttons>.button>.icon::before{display:block;position:relative;width:100%;top:0;text-align:center}.ui.labeled.icon.buttons .button>.icon{border-radius:0}.ui.labeled.icon.buttons .button:first-child>.icon{border-top-left-radius:.28571429rem;border-bottom-left-radius:.28571429rem}.ui.labeled.icon.buttons .button:last-child>.icon{border-top-right-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.labeled.icon.buttons .button:first-child>.icon{border-radius:0;border-top-left-radius:.28571429rem}.ui.vertical.labeled.icon.buttons .button:last-child>.icon{border-radius:0;border-bottom-left-radius:.28571429rem}.ui.labeled.icon.button>.loading.icon::before{animation:loader 2s linear infinite}.ui.button.toggle.active,.ui.buttons .button.toggle.active,.ui.toggle.buttons .active.button{background-color:#21ba45;box-shadow:none;text-shadow:none;color:#fff}.ui.button.toggle.active:hover{background-color:#16ab39;text-shadow:none;color:#fff}.ui.circular.button{border-radius:10em}.ui.circular.button>.icon{width:1em;vertical-align:baseline}.ui.buttons .or{position:relative;width:.3em;height:2.57142857em;z-index:3}.ui.buttons .or::before{position:absolute;text-align:center;border-radius:500rem;content:"or";top:50%;left:50%;background-color:#fff;text-shadow:none;margin-top:-.89285714em;margin-left:-.89285714em;width:1.78571429em;height:1.78571429em;line-height:1.78571429em;color:rgba(0,0,0,.4);font-style:normal;font-weight:700;box-shadow:0 0 0 1px transparent inset}.ui.buttons .or[data-text]::before{content:attr(data-text)}.ui.fluid.buttons .or{width:0!important}.ui.fluid.buttons .or::after{display:none}.ui.attached.button{position:relative;display:block;margin:0;border-radius:0;box-shadow:0 0 0 1px rgba(34,36,38,.15)}.ui.attached.top.button{border-radius:.28571429rem .28571429rem 0 0}.ui.attached.bottom.button{border-radius:0 0 .28571429rem .28571429rem}.ui.left.attached.button{display:inline-block;border-left:none;text-align:right;padding-right:.75em;border-radius:.28571429rem 0 0 .28571429rem}.ui.right.attached.button{display:inline-block;text-align:left;padding-left:.75em;border-radius:0 .28571429rem .28571429rem 0}.ui.attached.buttons{position:relative;display:flex;border-radius:0;width:auto!important;z-index:auto;margin-left:-1px;margin-right:-1px}.ui.attached.buttons .button{margin:0}.ui.attached.buttons .button:first-child{border-radius:0}.ui.attached.buttons .button:last-child{border-radius:0}.ui[class*="top attached"].buttons{margin-bottom:0;border-radius:.28571429rem .28571429rem 0 0}.ui[class*="top attached"].buttons .button:first-child{border-radius:.28571429rem 0 0 0}.ui[class*="top attached"].buttons .button:last-child{border-radius:0 .28571429rem 0 0}.ui[class*="bottom attached"].buttons{margin-top:-1px;border-radius:0 0 .28571429rem .28571429rem}.ui[class*="bottom attached"].buttons .button:first-child{border-radius:0 0 0 .28571429rem}.ui[class*="bottom attached"].buttons .button:last-child{border-radius:0 0 .28571429rem 0}.ui[class*="left attached"].buttons{display:inline-flex;margin-right:0;margin-left:-1px;border-radius:0 .28571429rem .28571429rem 0}.ui[class*="left attached"].buttons .button:first-child{margin-left:-1px;border-radius:0 .28571429rem 0 0}.ui[class*="left attached"].buttons .button:last-child{margin-left:-1px;border-radius:0 0 .28571429rem 0}.ui[class*="right attached"].buttons{display:inline-flex;margin-left:0;margin-right:-1px;border-radius:.28571429rem 0 0 .28571429rem}.ui[class*="right attached"].buttons .button:first-child{margin-left:-1px;border-radius:.28571429rem 0 0 0}.ui[class*="right attached"].buttons .button:last-child{margin-left:-1px;border-radius:0 0 0 .28571429rem}.ui.fluid.button,.ui.fluid.buttons{width:100%}.ui.fluid.button{display:block}.ui.two.buttons{width:100%}.ui.two.buttons>.button{width:50%}.ui.three.buttons{width:100%}.ui.three.buttons>.button{width:33.333%}.ui.four.buttons{width:100%}.ui.four.buttons>.button{width:25%}.ui.five.buttons{width:100%}.ui.five.buttons>.button{width:20%}.ui.six.buttons{width:100%}.ui.six.buttons>.button{width:16.666%}.ui.seven.buttons{width:100%}.ui.seven.buttons>.button{width:14.285%}.ui.eight.buttons{width:100%}.ui.eight.buttons>.button{width:12.5%}.ui.nine.buttons{width:100%}.ui.nine.buttons>.button{width:11.11%}.ui.ten.buttons{width:100%}.ui.ten.buttons>.button{width:10%}.ui.eleven.buttons{width:100%}.ui.eleven.buttons>.button{width:9.09%}.ui.twelve.buttons{width:100%}.ui.twelve.buttons>.button{width:8.3333%}.ui.fluid.vertical.buttons,.ui.fluid.vertical.buttons>.button{display:flex;width:auto;justify-content:center}.ui.two.vertical.buttons>.button{height:50%}.ui.three.vertical.buttons>.button{height:33.333%}.ui.four.vertical.buttons>.button{height:25%}.ui.five.vertical.buttons>.button{height:20%}.ui.six.vertical.buttons>.button{height:16.666%}.ui.seven.vertical.buttons>.button{height:14.285%}.ui.eight.vertical.buttons>.button{height:12.5%}.ui.nine.vertical.buttons>.button{height:11.11%}.ui.ten.vertical.buttons>.button{height:10%}.ui.eleven.vertical.buttons>.button{height:9.09%}.ui.twelve.vertical.buttons>.button{height:8.3333%}.ui.primary.button,.ui.primary.buttons .button{background-color:#2185d0;color:#fff;text-shadow:none;background-image:none}.ui.primary.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.primary.button:hover,.ui.primary.buttons .button:hover{background-color:#1678c2;color:#fff;text-shadow:none}.ui.primary.button:focus,.ui.primary.buttons .button:focus{background-color:#0d71bb;color:#fff;text-shadow:none}.ui.primary.button:active,.ui.primary.buttons .button:active{background-color:#1a69a4;color:#fff;text-shadow:none}.ui.primary.active.button,.ui.primary.button .active.button:active,.ui.primary.buttons .active.button,.ui.primary.buttons .active.button:active{background-color:#1279c6;color:#fff;text-shadow:none}.ui.basic.primary.button,.ui.basic.primary.buttons .button{background:0 0;box-shadow:0 0 0 1px #2185d0 inset;color:#2185d0}.ui.basic.primary.button:hover,.ui.basic.primary.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #1678c2 inset;color:#1678c2}.ui.basic.primary.button:focus,.ui.basic.primary.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #0d71bb inset;color:#1678c2}.ui.basic.primary.active.button,.ui.basic.primary.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #1279c6 inset;color:#1a69a4}.ui.basic.primary.button:active,.ui.basic.primary.buttons .button:active{box-shadow:0 0 0 1px #1a69a4 inset;color:#1a69a4}.ui.inverted.primary.button,.ui.inverted.primary.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #54c8ff inset;color:#54c8ff}.ui.inverted.primary.button.active,.ui.inverted.primary.button:active,.ui.inverted.primary.button:focus,.ui.inverted.primary.button:hover,.ui.inverted.primary.buttons .button.active,.ui.inverted.primary.buttons .button:active,.ui.inverted.primary.buttons .button:focus,.ui.inverted.primary.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.primary.button:hover,.ui.inverted.primary.buttons .button:hover{background-color:#21b8ff}.ui.inverted.primary.button:focus,.ui.inverted.primary.buttons .button:focus{background-color:#2bbbff}.ui.inverted.primary.active.button,.ui.inverted.primary.buttons .active.button{background-color:#3ac0ff}.ui.inverted.primary.button:active,.ui.inverted.primary.buttons .button:active{background-color:#21b8ff}.ui.inverted.primary.basic.button,.ui.inverted.primary.basic.buttons .button,.ui.inverted.primary.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.primary.basic.button:hover,.ui.inverted.primary.basic.buttons .button:hover,.ui.inverted.primary.buttons .basic.button:hover{box-shadow:0 0 0 2px #21b8ff inset;color:#54c8ff}.ui.inverted.primary.basic.button:focus,.ui.inverted.primary.basic.buttons .button:focus{box-shadow:0 0 0 2px #2bbbff inset;color:#54c8ff}.ui.inverted.primary.basic.active.button,.ui.inverted.primary.basic.buttons .active.button,.ui.inverted.primary.buttons .basic.active.button{box-shadow:0 0 0 2px #3ac0ff inset;color:#54c8ff}.ui.inverted.primary.basic.button:active,.ui.inverted.primary.basic.buttons .button:active,.ui.inverted.primary.buttons .basic.button:active{box-shadow:0 0 0 2px #21b8ff inset;color:#54c8ff}.ui.tertiary.primary.button,.ui.tertiary.primary.buttons .button,.ui.tertiary.primary.buttons .tertiary.button{background:0 0;box-shadow:none;color:#2185d0}.ui.tertiary.primary.button:hover,.ui.tertiary.primary.buttons .button:hover,.ui.tertiary.primary.buttons button:hover{box-shadow:inset 0 -.2em 0 #2b75ac;color:#2b75ac}.ui.tertiary.primary.button:focus,.ui.tertiary.primary.buttons .button:focus,.ui.tertiary.primary.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #216ea7;color:#216ea7}.ui.tertiary.primary.active.button,.ui.tertiary.primary.button:active,.ui.tertiary.primary.buttons .active.button,.ui.tertiary.primary.buttons .button:active,.ui.tertiary.primary.buttons .tertiary.active.button,.ui.tertiary.primary.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #007bd8;color:#1279c6}.ui.secondary.button,.ui.secondary.buttons .button{background-color:#1b1c1d;color:#fff;text-shadow:none;background-image:none}.ui.secondary.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.secondary.button:hover,.ui.secondary.buttons .button:hover{background-color:#27292a;color:#fff;text-shadow:none}.ui.secondary.button:focus,.ui.secondary.buttons .button:focus{background-color:#2e3032;color:#fff;text-shadow:none}.ui.secondary.button:active,.ui.secondary.buttons .button:active{background-color:#343637;color:#fff;text-shadow:none}.ui.secondary.active.button,.ui.secondary.button .active.button:active,.ui.secondary.buttons .active.button,.ui.secondary.buttons .active.button:active{background-color:#27292a;color:#fff;text-shadow:none}.ui.basic.secondary.button,.ui.basic.secondary.buttons .button{background:0 0;box-shadow:0 0 0 1px #1b1c1d inset;color:#1b1c1d}.ui.basic.secondary.button:hover,.ui.basic.secondary.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #27292a inset;color:#27292a}.ui.basic.secondary.button:focus,.ui.basic.secondary.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #2e3032 inset;color:#27292a}.ui.basic.secondary.active.button,.ui.basic.secondary.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #27292a inset;color:#343637}.ui.basic.secondary.button:active,.ui.basic.secondary.buttons .button:active{box-shadow:0 0 0 1px #343637 inset;color:#343637}.ui.inverted.secondary.button,.ui.inverted.secondary.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #545454 inset;color:#545454}.ui.inverted.secondary.button.active,.ui.inverted.secondary.button:active,.ui.inverted.secondary.button:focus,.ui.inverted.secondary.button:hover,.ui.inverted.secondary.buttons .button.active,.ui.inverted.secondary.buttons .button:active,.ui.inverted.secondary.buttons .button:focus,.ui.inverted.secondary.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.secondary.button:hover,.ui.inverted.secondary.buttons .button:hover{background-color:#6e6e6e}.ui.inverted.secondary.button:focus,.ui.inverted.secondary.buttons .button:focus{background-color:#686868}.ui.inverted.secondary.active.button,.ui.inverted.secondary.buttons .active.button{background-color:#616161}.ui.inverted.secondary.button:active,.ui.inverted.secondary.buttons .button:active{background-color:#6e6e6e}.ui.inverted.secondary.basic.button,.ui.inverted.secondary.basic.buttons .button,.ui.inverted.secondary.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.secondary.basic.button:hover,.ui.inverted.secondary.basic.buttons .button:hover,.ui.inverted.secondary.buttons .basic.button:hover{box-shadow:0 0 0 2px #6e6e6e inset;color:#545454}.ui.inverted.secondary.basic.button:focus,.ui.inverted.secondary.basic.buttons .button:focus{box-shadow:0 0 0 2px #686868 inset;color:#545454}.ui.inverted.secondary.basic.active.button,.ui.inverted.secondary.basic.buttons .active.button,.ui.inverted.secondary.buttons .basic.active.button{box-shadow:0 0 0 2px #616161 inset;color:#545454}.ui.inverted.secondary.basic.button:active,.ui.inverted.secondary.basic.buttons .button:active,.ui.inverted.secondary.buttons .basic.button:active{box-shadow:0 0 0 2px #6e6e6e inset;color:#545454}.ui.tertiary.secondary.button,.ui.tertiary.secondary.buttons .button,.ui.tertiary.secondary.buttons .tertiary.button{background:0 0;box-shadow:none;color:#1b1c1d}.ui.tertiary.secondary.button:hover,.ui.tertiary.secondary.buttons .button:hover,.ui.tertiary.secondary.buttons button:hover{box-shadow:inset 0 -.2em 0 #292929;color:#292929}.ui.tertiary.secondary.button:focus,.ui.tertiary.secondary.buttons .button:focus,.ui.tertiary.secondary.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #303030;color:#303030}.ui.tertiary.secondary.active.button,.ui.tertiary.secondary.button:active,.ui.tertiary.secondary.buttons .active.button,.ui.tertiary.secondary.buttons .button:active,.ui.tertiary.secondary.buttons .tertiary.active.button,.ui.tertiary.secondary.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #1f2933;color:#27292a}.ui.red.button,.ui.red.buttons .button{background-color:#db2828;color:#fff;text-shadow:none;background-image:none}.ui.red.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.red.button:hover,.ui.red.buttons .button:hover{background-color:#d01919;color:#fff;text-shadow:none}.ui.red.button:focus,.ui.red.buttons .button:focus{background-color:#ca1010;color:#fff;text-shadow:none}.ui.red.button:active,.ui.red.buttons .button:active{background-color:#b21e1e;color:#fff;text-shadow:none}.ui.red.active.button,.ui.red.button .active.button:active,.ui.red.buttons .active.button,.ui.red.buttons .active.button:active{background-color:#d41515;color:#fff;text-shadow:none}.ui.basic.red.button,.ui.basic.red.buttons .button{background:0 0;box-shadow:0 0 0 1px #db2828 inset;color:#db2828}.ui.basic.red.button:hover,.ui.basic.red.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #d01919 inset;color:#d01919}.ui.basic.red.button:focus,.ui.basic.red.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #ca1010 inset;color:#d01919}.ui.basic.red.active.button,.ui.basic.red.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #d41515 inset;color:#b21e1e}.ui.basic.red.button:active,.ui.basic.red.buttons .button:active{box-shadow:0 0 0 1px #b21e1e inset;color:#b21e1e}.ui.inverted.red.button,.ui.inverted.red.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #ff695e inset;color:#ff695e}.ui.inverted.red.button.active,.ui.inverted.red.button:active,.ui.inverted.red.button:focus,.ui.inverted.red.button:hover,.ui.inverted.red.buttons .button.active,.ui.inverted.red.buttons .button:active,.ui.inverted.red.buttons .button:focus,.ui.inverted.red.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.red.button:hover,.ui.inverted.red.buttons .button:hover{background-color:#ff392b}.ui.inverted.red.button:focus,.ui.inverted.red.buttons .button:focus{background-color:#ff4335}.ui.inverted.red.active.button,.ui.inverted.red.buttons .active.button{background-color:#ff5144}.ui.inverted.red.button:active,.ui.inverted.red.buttons .button:active{background-color:#ff392b}.ui.inverted.red.basic.button,.ui.inverted.red.basic.buttons .button,.ui.inverted.red.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.red.basic.button:hover,.ui.inverted.red.basic.buttons .button:hover,.ui.inverted.red.buttons .basic.button:hover{box-shadow:0 0 0 2px #ff392b inset;color:#ff695e}.ui.inverted.red.basic.button:focus,.ui.inverted.red.basic.buttons .button:focus{box-shadow:0 0 0 2px #ff4335 inset;color:#ff695e}.ui.inverted.red.basic.active.button,.ui.inverted.red.basic.buttons .active.button,.ui.inverted.red.buttons .basic.active.button{box-shadow:0 0 0 2px #ff5144 inset;color:#ff695e}.ui.inverted.red.basic.button:active,.ui.inverted.red.basic.buttons .button:active,.ui.inverted.red.buttons .basic.button:active{box-shadow:0 0 0 2px #ff392b inset;color:#ff695e}.ui.tertiary.red.button,.ui.tertiary.red.buttons .button,.ui.tertiary.red.buttons .tertiary.button{background:0 0;box-shadow:none;color:#db2828}.ui.tertiary.red.button:hover,.ui.tertiary.red.buttons .button:hover,.ui.tertiary.red.buttons button:hover{box-shadow:inset 0 -.2em 0 #b93131;color:#b93131}.ui.tertiary.red.button:focus,.ui.tertiary.red.buttons .button:focus,.ui.tertiary.red.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #b52626;color:#b52626}.ui.tertiary.red.active.button,.ui.tertiary.red.button:active,.ui.tertiary.red.buttons .active.button,.ui.tertiary.red.buttons .button:active,.ui.tertiary.red.buttons .tertiary.active.button,.ui.tertiary.red.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #ea0000;color:#d41515}.ui.orange.button,.ui.orange.buttons .button{background-color:#f2711c;color:#fff;text-shadow:none;background-image:none}.ui.orange.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.orange.button:hover,.ui.orange.buttons .button:hover{background-color:#f26202;color:#fff;text-shadow:none}.ui.orange.button:focus,.ui.orange.buttons .button:focus{background-color:#e55b00;color:#fff;text-shadow:none}.ui.orange.button:active,.ui.orange.buttons .button:active{background-color:#cf590c;color:#fff;text-shadow:none}.ui.orange.active.button,.ui.orange.button .active.button:active,.ui.orange.buttons .active.button,.ui.orange.buttons .active.button:active{background-color:#f56100;color:#fff;text-shadow:none}.ui.basic.orange.button,.ui.basic.orange.buttons .button{background:0 0;box-shadow:0 0 0 1px #f2711c inset;color:#f2711c}.ui.basic.orange.button:hover,.ui.basic.orange.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #f26202 inset;color:#f26202}.ui.basic.orange.button:focus,.ui.basic.orange.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #e55b00 inset;color:#f26202}.ui.basic.orange.active.button,.ui.basic.orange.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #f56100 inset;color:#cf590c}.ui.basic.orange.button:active,.ui.basic.orange.buttons .button:active{box-shadow:0 0 0 1px #cf590c inset;color:#cf590c}.ui.inverted.orange.button,.ui.inverted.orange.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #ff851b inset;color:#ff851b}.ui.inverted.orange.button.active,.ui.inverted.orange.button:active,.ui.inverted.orange.button:focus,.ui.inverted.orange.button:hover,.ui.inverted.orange.buttons .button.active,.ui.inverted.orange.buttons .button:active,.ui.inverted.orange.buttons .button:focus,.ui.inverted.orange.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.orange.button:hover,.ui.inverted.orange.buttons .button:hover{background-color:#e76b00}.ui.inverted.orange.button:focus,.ui.inverted.orange.buttons .button:focus{background-color:#f17000}.ui.inverted.orange.active.button,.ui.inverted.orange.buttons .active.button{background-color:#ff7701}.ui.inverted.orange.button:active,.ui.inverted.orange.buttons .button:active{background-color:#e76b00}.ui.inverted.orange.basic.button,.ui.inverted.orange.basic.buttons .button,.ui.inverted.orange.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.orange.basic.button:hover,.ui.inverted.orange.basic.buttons .button:hover,.ui.inverted.orange.buttons .basic.button:hover{box-shadow:0 0 0 2px #e76b00 inset;color:#ff851b}.ui.inverted.orange.basic.button:focus,.ui.inverted.orange.basic.buttons .button:focus{box-shadow:0 0 0 2px #f17000 inset;color:#ff851b}.ui.inverted.orange.basic.active.button,.ui.inverted.orange.basic.buttons .active.button,.ui.inverted.orange.buttons .basic.active.button{box-shadow:0 0 0 2px #ff7701 inset;color:#ff851b}.ui.inverted.orange.basic.button:active,.ui.inverted.orange.basic.buttons .button:active,.ui.inverted.orange.buttons .basic.button:active{box-shadow:0 0 0 2px #e76b00 inset;color:#ff851b}.ui.tertiary.orange.button,.ui.tertiary.orange.buttons .button,.ui.tertiary.orange.buttons .tertiary.button{background:0 0;box-shadow:none;color:#f2711c}.ui.tertiary.orange.button:hover,.ui.tertiary.orange.buttons .button:hover,.ui.tertiary.orange.buttons button:hover{box-shadow:inset 0 -.2em 0 #da671b;color:#da671b}.ui.tertiary.orange.button:focus,.ui.tertiary.orange.buttons .button:focus,.ui.tertiary.orange.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #ce6017;color:#ce6017}.ui.tertiary.orange.active.button,.ui.tertiary.orange.button:active,.ui.tertiary.orange.buttons .active.button,.ui.tertiary.orange.buttons .button:active,.ui.tertiary.orange.buttons .tertiary.active.button,.ui.tertiary.orange.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #f56100;color:#f56100}.ui.yellow.button,.ui.yellow.buttons .button{background-color:#fbbd08;color:#fff;text-shadow:none;background-image:none}.ui.yellow.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.yellow.button:hover,.ui.yellow.buttons .button:hover{background-color:#eaae00;color:#fff;text-shadow:none}.ui.yellow.button:focus,.ui.yellow.buttons .button:focus{background-color:#daa300;color:#fff;text-shadow:none}.ui.yellow.button:active,.ui.yellow.buttons .button:active{background-color:#cd9903;color:#fff;text-shadow:none}.ui.yellow.active.button,.ui.yellow.button .active.button:active,.ui.yellow.buttons .active.button,.ui.yellow.buttons .active.button:active{background-color:#eaae00;color:#fff;text-shadow:none}.ui.basic.yellow.button,.ui.basic.yellow.buttons .button{background:0 0;box-shadow:0 0 0 1px #fbbd08 inset;color:#fbbd08}.ui.basic.yellow.button:hover,.ui.basic.yellow.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #eaae00 inset;color:#eaae00}.ui.basic.yellow.button:focus,.ui.basic.yellow.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #daa300 inset;color:#eaae00}.ui.basic.yellow.active.button,.ui.basic.yellow.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #eaae00 inset;color:#cd9903}.ui.basic.yellow.button:active,.ui.basic.yellow.buttons .button:active{box-shadow:0 0 0 1px #cd9903 inset;color:#cd9903}.ui.inverted.yellow.button,.ui.inverted.yellow.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #ffe21f inset;color:#ffe21f}.ui.inverted.yellow.button.active,.ui.inverted.yellow.button:active,.ui.inverted.yellow.button:focus,.ui.inverted.yellow.button:hover,.ui.inverted.yellow.buttons .button.active,.ui.inverted.yellow.buttons .button:active,.ui.inverted.yellow.buttons .button:focus,.ui.inverted.yellow.buttons .button:hover{box-shadow:none;color:rgba(0,0,0,.6)}.ui.inverted.yellow.button:hover,.ui.inverted.yellow.buttons .button:hover{background-color:#ebcd00}.ui.inverted.yellow.button:focus,.ui.inverted.yellow.buttons .button:focus{background-color:#f5d500}.ui.inverted.yellow.active.button,.ui.inverted.yellow.buttons .active.button{background-color:#ffdf05}.ui.inverted.yellow.button:active,.ui.inverted.yellow.buttons .button:active{background-color:#ebcd00}.ui.inverted.yellow.basic.button,.ui.inverted.yellow.basic.buttons .button,.ui.inverted.yellow.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.yellow.basic.button:hover,.ui.inverted.yellow.basic.buttons .button:hover,.ui.inverted.yellow.buttons .basic.button:hover{box-shadow:0 0 0 2px #ebcd00 inset;color:#ffe21f}.ui.inverted.yellow.basic.button:focus,.ui.inverted.yellow.basic.buttons .button:focus{box-shadow:0 0 0 2px #f5d500 inset;color:#ffe21f}.ui.inverted.yellow.basic.active.button,.ui.inverted.yellow.basic.buttons .active.button,.ui.inverted.yellow.buttons .basic.active.button{box-shadow:0 0 0 2px #ffdf05 inset;color:#ffe21f}.ui.inverted.yellow.basic.button:active,.ui.inverted.yellow.basic.buttons .button:active,.ui.inverted.yellow.buttons .basic.button:active{box-shadow:0 0 0 2px #ebcd00 inset;color:#ffe21f}.ui.tertiary.yellow.button,.ui.tertiary.yellow.buttons .button,.ui.tertiary.yellow.buttons .tertiary.button{background:0 0;box-shadow:none;color:#fbbd08}.ui.tertiary.yellow.button:hover,.ui.tertiary.yellow.buttons .button:hover,.ui.tertiary.yellow.buttons button:hover{box-shadow:inset 0 -.2em 0 #d2a217;color:#d2a217}.ui.tertiary.yellow.button:focus,.ui.tertiary.yellow.buttons .button:focus,.ui.tertiary.yellow.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #c49816;color:#c49816}.ui.tertiary.yellow.active.button,.ui.tertiary.yellow.button:active,.ui.tertiary.yellow.buttons .active.button,.ui.tertiary.yellow.buttons .button:active,.ui.tertiary.yellow.buttons .tertiary.active.button,.ui.tertiary.yellow.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #eaae00;color:#eaae00}.ui.olive.button,.ui.olive.buttons .button{background-color:#b5cc18;color:#fff;text-shadow:none;background-image:none}.ui.olive.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.olive.button:hover,.ui.olive.buttons .button:hover{background-color:#a7bd0d;color:#fff;text-shadow:none}.ui.olive.button:focus,.ui.olive.buttons .button:focus{background-color:#a0b605;color:#fff;text-shadow:none}.ui.olive.button:active,.ui.olive.buttons .button:active{background-color:#8d9e13;color:#fff;text-shadow:none}.ui.olive.active.button,.ui.olive.button .active.button:active,.ui.olive.buttons .active.button,.ui.olive.buttons .active.button:active{background-color:#aac109;color:#fff;text-shadow:none}.ui.basic.olive.button,.ui.basic.olive.buttons .button{background:0 0;box-shadow:0 0 0 1px #b5cc18 inset;color:#b5cc18}.ui.basic.olive.button:hover,.ui.basic.olive.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #a7bd0d inset;color:#a7bd0d}.ui.basic.olive.button:focus,.ui.basic.olive.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #a0b605 inset;color:#a7bd0d}.ui.basic.olive.active.button,.ui.basic.olive.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #aac109 inset;color:#8d9e13}.ui.basic.olive.button:active,.ui.basic.olive.buttons .button:active{box-shadow:0 0 0 1px #8d9e13 inset;color:#8d9e13}.ui.inverted.olive.button,.ui.inverted.olive.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #d9e778 inset;color:#d9e778}.ui.inverted.olive.button.active,.ui.inverted.olive.button:active,.ui.inverted.olive.button:focus,.ui.inverted.olive.button:hover,.ui.inverted.olive.buttons .button.active,.ui.inverted.olive.buttons .button:active,.ui.inverted.olive.buttons .button:focus,.ui.inverted.olive.buttons .button:hover{box-shadow:none;color:rgba(0,0,0,.6)}.ui.inverted.olive.button:hover,.ui.inverted.olive.buttons .button:hover{background-color:#d2e745}.ui.inverted.olive.button:focus,.ui.inverted.olive.buttons .button:focus{background-color:#daef47}.ui.inverted.olive.active.button,.ui.inverted.olive.buttons .active.button{background-color:#daed59}.ui.inverted.olive.button:active,.ui.inverted.olive.buttons .button:active{background-color:#cddf4d}.ui.inverted.olive.basic.button,.ui.inverted.olive.basic.buttons .button,.ui.inverted.olive.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.olive.basic.button:hover,.ui.inverted.olive.basic.buttons .button:hover,.ui.inverted.olive.buttons .basic.button:hover{box-shadow:0 0 0 2px #d2e745 inset;color:#d9e778}.ui.inverted.olive.basic.button:focus,.ui.inverted.olive.basic.buttons .button:focus{box-shadow:0 0 0 2px #daef47 inset;color:#d9e778}.ui.inverted.olive.basic.active.button,.ui.inverted.olive.basic.buttons .active.button,.ui.inverted.olive.buttons .basic.active.button{box-shadow:0 0 0 2px #daed59 inset;color:#d9e778}.ui.inverted.olive.basic.button:active,.ui.inverted.olive.basic.buttons .button:active,.ui.inverted.olive.buttons .basic.button:active{box-shadow:0 0 0 2px #cddf4d inset;color:#d9e778}.ui.tertiary.olive.button,.ui.tertiary.olive.buttons .button,.ui.tertiary.olive.buttons .tertiary.button{background:0 0;box-shadow:none;color:#b5cc18}.ui.tertiary.olive.button:hover,.ui.tertiary.olive.buttons .button:hover,.ui.tertiary.olive.buttons button:hover{box-shadow:inset 0 -.2em 0 #98a922;color:#98a922}.ui.tertiary.olive.button:focus,.ui.tertiary.olive.buttons .button:focus,.ui.tertiary.olive.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #92a418;color:#92a418}.ui.tertiary.olive.active.button,.ui.tertiary.olive.button:active,.ui.tertiary.olive.buttons .active.button,.ui.tertiary.olive.buttons .button:active,.ui.tertiary.olive.buttons .tertiary.active.button,.ui.tertiary.olive.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #b1cb00;color:#aac109}.ui.green.button,.ui.green.buttons .button{background-color:#21ba45;color:#fff;text-shadow:none;background-image:none}.ui.green.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.green.button:hover,.ui.green.buttons .button:hover{background-color:#16ab39;color:#fff;text-shadow:none}.ui.green.button:focus,.ui.green.buttons .button:focus{background-color:#0ea432;color:#fff;text-shadow:none}.ui.green.button:active,.ui.green.buttons .button:active{background-color:#198f35;color:#fff;text-shadow:none}.ui.green.active.button,.ui.green.button .active.button:active,.ui.green.buttons .active.button,.ui.green.buttons .active.button:active{background-color:#13ae38;color:#fff;text-shadow:none}.ui.basic.green.button,.ui.basic.green.buttons .button{background:0 0;box-shadow:0 0 0 1px #21ba45 inset;color:#21ba45}.ui.basic.green.button:hover,.ui.basic.green.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #16ab39 inset;color:#16ab39}.ui.basic.green.button:focus,.ui.basic.green.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #0ea432 inset;color:#16ab39}.ui.basic.green.active.button,.ui.basic.green.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #13ae38 inset;color:#198f35}.ui.basic.green.button:active,.ui.basic.green.buttons .button:active{box-shadow:0 0 0 1px #198f35 inset;color:#198f35}.ui.inverted.green.button,.ui.inverted.green.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #2ecc40 inset;color:#2ecc40}.ui.inverted.green.button.active,.ui.inverted.green.button:active,.ui.inverted.green.button:focus,.ui.inverted.green.button:hover,.ui.inverted.green.buttons .button.active,.ui.inverted.green.buttons .button:active,.ui.inverted.green.buttons .button:focus,.ui.inverted.green.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.green.button:hover,.ui.inverted.green.buttons .button:hover{background-color:#1ea92e}.ui.inverted.green.button:focus,.ui.inverted.green.buttons .button:focus{background-color:#19b82b}.ui.inverted.green.active.button,.ui.inverted.green.buttons .active.button{background-color:#1fc231}.ui.inverted.green.button:active,.ui.inverted.green.buttons .button:active{background-color:#25a233}.ui.inverted.green.basic.button,.ui.inverted.green.basic.buttons .button,.ui.inverted.green.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.green.basic.button:hover,.ui.inverted.green.basic.buttons .button:hover,.ui.inverted.green.buttons .basic.button:hover{box-shadow:0 0 0 2px #1ea92e inset;color:#2ecc40}.ui.inverted.green.basic.button:focus,.ui.inverted.green.basic.buttons .button:focus{box-shadow:0 0 0 2px #19b82b inset;color:#2ecc40}.ui.inverted.green.basic.active.button,.ui.inverted.green.basic.buttons .active.button,.ui.inverted.green.buttons .basic.active.button{box-shadow:0 0 0 2px #1fc231 inset;color:#2ecc40}.ui.inverted.green.basic.button:active,.ui.inverted.green.basic.buttons .button:active,.ui.inverted.green.buttons .basic.button:active{box-shadow:0 0 0 2px #25a233 inset;color:#2ecc40}.ui.tertiary.green.button,.ui.tertiary.green.buttons .button,.ui.tertiary.green.buttons .tertiary.button{background:0 0;box-shadow:none;color:#21ba45}.ui.tertiary.green.button:hover,.ui.tertiary.green.buttons .button:hover,.ui.tertiary.green.buttons button:hover{box-shadow:inset 0 -.2em 0 #2a9844;color:#2a9844}.ui.tertiary.green.button:focus,.ui.tertiary.green.buttons .button:focus,.ui.tertiary.green.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #20923b;color:#20923b}.ui.tertiary.green.active.button,.ui.tertiary.green.button:active,.ui.tertiary.green.buttons .active.button,.ui.tertiary.green.buttons .button:active,.ui.tertiary.green.buttons .tertiary.active.button,.ui.tertiary.green.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #00c22e;color:#13ae38}.ui.teal.button,.ui.teal.buttons .button{background-color:#00b5ad;color:#fff;text-shadow:none;background-image:none}.ui.teal.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.teal.button:hover,.ui.teal.buttons .button:hover{background-color:#009c95;color:#fff;text-shadow:none}.ui.teal.button:focus,.ui.teal.buttons .button:focus{background-color:#008c86;color:#fff;text-shadow:none}.ui.teal.button:active,.ui.teal.buttons .button:active{background-color:#00827c;color:#fff;text-shadow:none}.ui.teal.active.button,.ui.teal.button .active.button:active,.ui.teal.buttons .active.button,.ui.teal.buttons .active.button:active{background-color:#009c95;color:#fff;text-shadow:none}.ui.basic.teal.button,.ui.basic.teal.buttons .button{background:0 0;box-shadow:0 0 0 1px #00b5ad inset;color:#00b5ad}.ui.basic.teal.button:hover,.ui.basic.teal.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #009c95 inset;color:#009c95}.ui.basic.teal.button:focus,.ui.basic.teal.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #008c86 inset;color:#009c95}.ui.basic.teal.active.button,.ui.basic.teal.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #009c95 inset;color:#00827c}.ui.basic.teal.button:active,.ui.basic.teal.buttons .button:active{box-shadow:0 0 0 1px #00827c inset;color:#00827c}.ui.inverted.teal.button,.ui.inverted.teal.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #6dffff inset;color:#6dffff}.ui.inverted.teal.button.active,.ui.inverted.teal.button:active,.ui.inverted.teal.button:focus,.ui.inverted.teal.button:hover,.ui.inverted.teal.buttons .button.active,.ui.inverted.teal.buttons .button:active,.ui.inverted.teal.buttons .button:focus,.ui.inverted.teal.buttons .button:hover{box-shadow:none;color:rgba(0,0,0,.6)}.ui.inverted.teal.button:hover,.ui.inverted.teal.buttons .button:hover{background-color:#3affff}.ui.inverted.teal.button:focus,.ui.inverted.teal.buttons .button:focus{background-color:#4ff}.ui.inverted.teal.active.button,.ui.inverted.teal.buttons .active.button{background-color:#54ffff}.ui.inverted.teal.button:active,.ui.inverted.teal.buttons .button:active{background-color:#3affff}.ui.inverted.teal.basic.button,.ui.inverted.teal.basic.buttons .button,.ui.inverted.teal.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.teal.basic.button:hover,.ui.inverted.teal.basic.buttons .button:hover,.ui.inverted.teal.buttons .basic.button:hover{box-shadow:0 0 0 2px #3affff inset;color:#6dffff}.ui.inverted.teal.basic.button:focus,.ui.inverted.teal.basic.buttons .button:focus{box-shadow:0 0 0 2px #4ff inset;color:#6dffff}.ui.inverted.teal.basic.active.button,.ui.inverted.teal.basic.buttons .active.button,.ui.inverted.teal.buttons .basic.active.button{box-shadow:0 0 0 2px #54ffff inset;color:#6dffff}.ui.inverted.teal.basic.button:active,.ui.inverted.teal.basic.buttons .button:active,.ui.inverted.teal.buttons .basic.button:active{box-shadow:0 0 0 2px #3affff inset;color:#6dffff}.ui.tertiary.teal.button,.ui.tertiary.teal.buttons .button,.ui.tertiary.teal.buttons .tertiary.button{background:0 0;box-shadow:none;color:#00b5ad}.ui.tertiary.teal.button:hover,.ui.tertiary.teal.buttons .button:hover,.ui.tertiary.teal.buttons button:hover{box-shadow:inset 0 -.2em 0 #108c86;color:#108c86}.ui.tertiary.teal.button:focus,.ui.tertiary.teal.buttons .button:focus,.ui.tertiary.teal.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #0e7e79;color:#0e7e79}.ui.tertiary.teal.active.button,.ui.tertiary.teal.button:active,.ui.tertiary.teal.buttons .active.button,.ui.tertiary.teal.buttons .button:active,.ui.tertiary.teal.buttons .tertiary.active.button,.ui.tertiary.teal.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #009c95;color:#009c95}.ui.blue.button,.ui.blue.buttons .button{background-color:#2185d0;color:#fff;text-shadow:none;background-image:none}.ui.blue.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.blue.button:hover,.ui.blue.buttons .button:hover{background-color:#1678c2;color:#fff;text-shadow:none}.ui.blue.button:focus,.ui.blue.buttons .button:focus{background-color:#0d71bb;color:#fff;text-shadow:none}.ui.blue.button:active,.ui.blue.buttons .button:active{background-color:#1a69a4;color:#fff;text-shadow:none}.ui.blue.active.button,.ui.blue.button .active.button:active,.ui.blue.buttons .active.button,.ui.blue.buttons .active.button:active{background-color:#1279c6;color:#fff;text-shadow:none}.ui.basic.blue.button,.ui.basic.blue.buttons .button{background:0 0;box-shadow:0 0 0 1px #2185d0 inset;color:#2185d0}.ui.basic.blue.button:hover,.ui.basic.blue.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #1678c2 inset;color:#1678c2}.ui.basic.blue.button:focus,.ui.basic.blue.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #0d71bb inset;color:#1678c2}.ui.basic.blue.active.button,.ui.basic.blue.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #1279c6 inset;color:#1a69a4}.ui.basic.blue.button:active,.ui.basic.blue.buttons .button:active{box-shadow:0 0 0 1px #1a69a4 inset;color:#1a69a4}.ui.inverted.blue.button,.ui.inverted.blue.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #54c8ff inset;color:#54c8ff}.ui.inverted.blue.button.active,.ui.inverted.blue.button:active,.ui.inverted.blue.button:focus,.ui.inverted.blue.button:hover,.ui.inverted.blue.buttons .button.active,.ui.inverted.blue.buttons .button:active,.ui.inverted.blue.buttons .button:focus,.ui.inverted.blue.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.blue.button:hover,.ui.inverted.blue.buttons .button:hover{background-color:#21b8ff}.ui.inverted.blue.button:focus,.ui.inverted.blue.buttons .button:focus{background-color:#2bbbff}.ui.inverted.blue.active.button,.ui.inverted.blue.buttons .active.button{background-color:#3ac0ff}.ui.inverted.blue.button:active,.ui.inverted.blue.buttons .button:active{background-color:#21b8ff}.ui.inverted.blue.basic.button,.ui.inverted.blue.basic.buttons .button,.ui.inverted.blue.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.blue.basic.button:hover,.ui.inverted.blue.basic.buttons .button:hover,.ui.inverted.blue.buttons .basic.button:hover{box-shadow:0 0 0 2px #21b8ff inset;color:#54c8ff}.ui.inverted.blue.basic.button:focus,.ui.inverted.blue.basic.buttons .button:focus{box-shadow:0 0 0 2px #2bbbff inset;color:#54c8ff}.ui.inverted.blue.basic.active.button,.ui.inverted.blue.basic.buttons .active.button,.ui.inverted.blue.buttons .basic.active.button{box-shadow:0 0 0 2px #3ac0ff inset;color:#54c8ff}.ui.inverted.blue.basic.button:active,.ui.inverted.blue.basic.buttons .button:active,.ui.inverted.blue.buttons .basic.button:active{box-shadow:0 0 0 2px #21b8ff inset;color:#54c8ff}.ui.tertiary.blue.button,.ui.tertiary.blue.buttons .button,.ui.tertiary.blue.buttons .tertiary.button{background:0 0;box-shadow:none;color:#2185d0}.ui.tertiary.blue.button:hover,.ui.tertiary.blue.buttons .button:hover,.ui.tertiary.blue.buttons button:hover{box-shadow:inset 0 -.2em 0 #2b75ac;color:#2b75ac}.ui.tertiary.blue.button:focus,.ui.tertiary.blue.buttons .button:focus,.ui.tertiary.blue.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #216ea7;color:#216ea7}.ui.tertiary.blue.active.button,.ui.tertiary.blue.button:active,.ui.tertiary.blue.buttons .active.button,.ui.tertiary.blue.buttons .button:active,.ui.tertiary.blue.buttons .tertiary.active.button,.ui.tertiary.blue.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #007bd8;color:#1279c6}.ui.violet.button,.ui.violet.buttons .button{background-color:#6435c9;color:#fff;text-shadow:none;background-image:none}.ui.violet.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.violet.button:hover,.ui.violet.buttons .button:hover{background-color:#5829bb;color:#fff;text-shadow:none}.ui.violet.button:focus,.ui.violet.buttons .button:focus{background-color:#4f20b5;color:#fff;text-shadow:none}.ui.violet.button:active,.ui.violet.buttons .button:active{background-color:#502aa1;color:#fff;text-shadow:none}.ui.violet.active.button,.ui.violet.button .active.button:active,.ui.violet.buttons .active.button,.ui.violet.buttons .active.button:active{background-color:#5626bf;color:#fff;text-shadow:none}.ui.basic.violet.button,.ui.basic.violet.buttons .button{background:0 0;box-shadow:0 0 0 1px #6435c9 inset;color:#6435c9}.ui.basic.violet.button:hover,.ui.basic.violet.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #5829bb inset;color:#5829bb}.ui.basic.violet.button:focus,.ui.basic.violet.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #4f20b5 inset;color:#5829bb}.ui.basic.violet.active.button,.ui.basic.violet.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #5626bf inset;color:#502aa1}.ui.basic.violet.button:active,.ui.basic.violet.buttons .button:active{box-shadow:0 0 0 1px #502aa1 inset;color:#502aa1}.ui.inverted.violet.button,.ui.inverted.violet.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #a291fb inset;color:#a291fb}.ui.inverted.violet.button.active,.ui.inverted.violet.button:active,.ui.inverted.violet.button:focus,.ui.inverted.violet.button:hover,.ui.inverted.violet.buttons .button.active,.ui.inverted.violet.buttons .button:active,.ui.inverted.violet.buttons .button:focus,.ui.inverted.violet.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.violet.button:hover,.ui.inverted.violet.buttons .button:hover{background-color:#745aff}.ui.inverted.violet.button:focus,.ui.inverted.violet.buttons .button:focus{background-color:#7d64ff}.ui.inverted.violet.active.button,.ui.inverted.violet.buttons .active.button{background-color:#8a73ff}.ui.inverted.violet.button:active,.ui.inverted.violet.buttons .button:active{background-color:#7860f9}.ui.inverted.violet.basic.button,.ui.inverted.violet.basic.buttons .button,.ui.inverted.violet.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.violet.basic.button:hover,.ui.inverted.violet.basic.buttons .button:hover,.ui.inverted.violet.buttons .basic.button:hover{box-shadow:0 0 0 2px #745aff inset;color:#a291fb}.ui.inverted.violet.basic.button:focus,.ui.inverted.violet.basic.buttons .button:focus{box-shadow:0 0 0 2px #7d64ff inset;color:#a291fb}.ui.inverted.violet.basic.active.button,.ui.inverted.violet.basic.buttons .active.button,.ui.inverted.violet.buttons .basic.active.button{box-shadow:0 0 0 2px #8a73ff inset;color:#a291fb}.ui.inverted.violet.basic.button:active,.ui.inverted.violet.basic.buttons .button:active,.ui.inverted.violet.buttons .basic.button:active{box-shadow:0 0 0 2px #7860f9 inset;color:#a291fb}.ui.tertiary.violet.button,.ui.tertiary.violet.buttons .button,.ui.tertiary.violet.buttons .tertiary.button{background:0 0;box-shadow:none;color:#6435c9}.ui.tertiary.violet.button:hover,.ui.tertiary.violet.buttons .button:hover,.ui.tertiary.violet.buttons button:hover{box-shadow:inset 0 -.2em 0 #6040a5;color:#6040a5}.ui.tertiary.violet.button:focus,.ui.tertiary.violet.buttons .button:focus,.ui.tertiary.violet.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #5735a0;color:#5735a0}.ui.tertiary.violet.active.button,.ui.tertiary.violet.button:active,.ui.tertiary.violet.buttons .active.button,.ui.tertiary.violet.buttons .button:active,.ui.tertiary.violet.buttons .tertiary.active.button,.ui.tertiary.violet.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #4e0fd6;color:#5626bf}.ui.purple.button,.ui.purple.buttons .button{background-color:#a333c8;color:#fff;text-shadow:none;background-image:none}.ui.purple.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.purple.button:hover,.ui.purple.buttons .button:hover{background-color:#9627ba;color:#fff;text-shadow:none}.ui.purple.button:focus,.ui.purple.buttons .button:focus{background-color:#8f1eb4;color:#fff;text-shadow:none}.ui.purple.button:active,.ui.purple.buttons .button:active{background-color:#82299f;color:#fff;text-shadow:none}.ui.purple.active.button,.ui.purple.button .active.button:active,.ui.purple.buttons .active.button,.ui.purple.buttons .active.button:active{background-color:#9724be;color:#fff;text-shadow:none}.ui.basic.purple.button,.ui.basic.purple.buttons .button{background:0 0;box-shadow:0 0 0 1px #a333c8 inset;color:#a333c8}.ui.basic.purple.button:hover,.ui.basic.purple.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #9627ba inset;color:#9627ba}.ui.basic.purple.button:focus,.ui.basic.purple.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #8f1eb4 inset;color:#9627ba}.ui.basic.purple.active.button,.ui.basic.purple.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #9724be inset;color:#82299f}.ui.basic.purple.button:active,.ui.basic.purple.buttons .button:active{box-shadow:0 0 0 1px #82299f inset;color:#82299f}.ui.inverted.purple.button,.ui.inverted.purple.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #dc73ff inset;color:#dc73ff}.ui.inverted.purple.button.active,.ui.inverted.purple.button:active,.ui.inverted.purple.button:focus,.ui.inverted.purple.button:hover,.ui.inverted.purple.buttons .button.active,.ui.inverted.purple.buttons .button:active,.ui.inverted.purple.buttons .button:focus,.ui.inverted.purple.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.purple.button:hover,.ui.inverted.purple.buttons .button:hover{background-color:#cf40ff}.ui.inverted.purple.button:focus,.ui.inverted.purple.buttons .button:focus{background-color:#d24aff}.ui.inverted.purple.active.button,.ui.inverted.purple.buttons .active.button{background-color:#d65aff}.ui.inverted.purple.button:active,.ui.inverted.purple.buttons .button:active{background-color:#cf40ff}.ui.inverted.purple.basic.button,.ui.inverted.purple.basic.buttons .button,.ui.inverted.purple.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.purple.basic.button:hover,.ui.inverted.purple.basic.buttons .button:hover,.ui.inverted.purple.buttons .basic.button:hover{box-shadow:0 0 0 2px #cf40ff inset;color:#dc73ff}.ui.inverted.purple.basic.button:focus,.ui.inverted.purple.basic.buttons .button:focus{box-shadow:0 0 0 2px #d24aff inset;color:#dc73ff}.ui.inverted.purple.basic.active.button,.ui.inverted.purple.basic.buttons .active.button,.ui.inverted.purple.buttons .basic.active.button{box-shadow:0 0 0 2px #d65aff inset;color:#dc73ff}.ui.inverted.purple.basic.button:active,.ui.inverted.purple.basic.buttons .button:active,.ui.inverted.purple.buttons .basic.button:active{box-shadow:0 0 0 2px #cf40ff inset;color:#dc73ff}.ui.tertiary.purple.button,.ui.tertiary.purple.buttons .button,.ui.tertiary.purple.buttons .tertiary.button{background:0 0;box-shadow:none;color:#a333c8}.ui.tertiary.purple.button:hover,.ui.tertiary.purple.buttons .button:hover,.ui.tertiary.purple.buttons button:hover{box-shadow:inset 0 -.2em 0 #8a3ea4;color:#8a3ea4}.ui.tertiary.purple.button:focus,.ui.tertiary.purple.buttons .button:focus,.ui.tertiary.purple.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #84339f;color:#84339f}.ui.tertiary.purple.active.button,.ui.tertiary.purple.button:active,.ui.tertiary.purple.buttons .active.button,.ui.tertiary.purple.buttons .button:active,.ui.tertiary.purple.buttons .tertiary.active.button,.ui.tertiary.purple.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #a30dd4;color:#9724be}.ui.pink.button,.ui.pink.buttons .button{background-color:#e03997;color:#fff;text-shadow:none;background-image:none}.ui.pink.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.pink.button:hover,.ui.pink.buttons .button:hover{background-color:#e61a8d;color:#fff;text-shadow:none}.ui.pink.button:focus,.ui.pink.buttons .button:focus{background-color:#e10f85;color:#fff;text-shadow:none}.ui.pink.button:active,.ui.pink.buttons .button:active{background-color:#c71f7e;color:#fff;text-shadow:none}.ui.pink.active.button,.ui.pink.button .active.button:active,.ui.pink.buttons .active.button,.ui.pink.buttons .active.button:active{background-color:#ea158d;color:#fff;text-shadow:none}.ui.basic.pink.button,.ui.basic.pink.buttons .button{background:0 0;box-shadow:0 0 0 1px #e03997 inset;color:#e03997}.ui.basic.pink.button:hover,.ui.basic.pink.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #e61a8d inset;color:#e61a8d}.ui.basic.pink.button:focus,.ui.basic.pink.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #e10f85 inset;color:#e61a8d}.ui.basic.pink.active.button,.ui.basic.pink.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #ea158d inset;color:#c71f7e}.ui.basic.pink.button:active,.ui.basic.pink.buttons .button:active{box-shadow:0 0 0 1px #c71f7e inset;color:#c71f7e}.ui.inverted.pink.button,.ui.inverted.pink.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #ff8edf inset;color:#ff8edf}.ui.inverted.pink.button.active,.ui.inverted.pink.button:active,.ui.inverted.pink.button:focus,.ui.inverted.pink.button:hover,.ui.inverted.pink.buttons .button.active,.ui.inverted.pink.buttons .button:active,.ui.inverted.pink.buttons .button:focus,.ui.inverted.pink.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.pink.button:hover,.ui.inverted.pink.buttons .button:hover{background-color:#ff5bd1}.ui.inverted.pink.button:focus,.ui.inverted.pink.buttons .button:focus{background-color:#ff65d3}.ui.inverted.pink.active.button,.ui.inverted.pink.buttons .active.button{background-color:#ff74d8}.ui.inverted.pink.button:active,.ui.inverted.pink.buttons .button:active{background-color:#ff5bd1}.ui.inverted.pink.basic.button,.ui.inverted.pink.basic.buttons .button,.ui.inverted.pink.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.pink.basic.button:hover,.ui.inverted.pink.basic.buttons .button:hover,.ui.inverted.pink.buttons .basic.button:hover{box-shadow:0 0 0 2px #ff5bd1 inset;color:#ff8edf}.ui.inverted.pink.basic.button:focus,.ui.inverted.pink.basic.buttons .button:focus{box-shadow:0 0 0 2px #ff65d3 inset;color:#ff8edf}.ui.inverted.pink.basic.active.button,.ui.inverted.pink.basic.buttons .active.button,.ui.inverted.pink.buttons .basic.active.button{box-shadow:0 0 0 2px #ff74d8 inset;color:#ff8edf}.ui.inverted.pink.basic.button:active,.ui.inverted.pink.basic.buttons .button:active,.ui.inverted.pink.buttons .basic.button:active{box-shadow:0 0 0 2px #ff5bd1 inset;color:#ff8edf}.ui.tertiary.pink.button,.ui.tertiary.pink.buttons .button,.ui.tertiary.pink.buttons .tertiary.button{background:0 0;box-shadow:none;color:#e03997}.ui.tertiary.pink.button:hover,.ui.tertiary.pink.buttons .button:hover,.ui.tertiary.pink.buttons button:hover{box-shadow:inset 0 -.2em 0 #cc3389;color:#cc3389}.ui.tertiary.pink.button:focus,.ui.tertiary.pink.buttons .button:focus,.ui.tertiary.pink.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #c92782;color:#c92782}.ui.tertiary.pink.active.button,.ui.tertiary.pink.button:active,.ui.tertiary.pink.buttons .active.button,.ui.tertiary.pink.buttons .button:active,.ui.tertiary.pink.buttons .tertiary.active.button,.ui.tertiary.pink.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #ff0090;color:#ea158d}.ui.brown.button,.ui.brown.buttons .button{background-color:#a5673f;color:#fff;text-shadow:none;background-image:none}.ui.brown.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.brown.button:hover,.ui.brown.buttons .button:hover{background-color:#975b33;color:#fff;text-shadow:none}.ui.brown.button:focus,.ui.brown.buttons .button:focus{background-color:#90532b;color:#fff;text-shadow:none}.ui.brown.button:active,.ui.brown.buttons .button:active{background-color:#805031;color:#fff;text-shadow:none}.ui.brown.active.button,.ui.brown.button .active.button:active,.ui.brown.buttons .active.button,.ui.brown.buttons .active.button:active{background-color:#995a31;color:#fff;text-shadow:none}.ui.basic.brown.button,.ui.basic.brown.buttons .button{background:0 0;box-shadow:0 0 0 1px #a5673f inset;color:#a5673f}.ui.basic.brown.button:hover,.ui.basic.brown.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #975b33 inset;color:#975b33}.ui.basic.brown.button:focus,.ui.basic.brown.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #90532b inset;color:#975b33}.ui.basic.brown.active.button,.ui.basic.brown.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #995a31 inset;color:#805031}.ui.basic.brown.button:active,.ui.basic.brown.buttons .button:active{box-shadow:0 0 0 1px #805031 inset;color:#805031}.ui.inverted.brown.button,.ui.inverted.brown.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #d67c1c inset;color:#d67c1c}.ui.inverted.brown.button.active,.ui.inverted.brown.button:active,.ui.inverted.brown.button:focus,.ui.inverted.brown.button:hover,.ui.inverted.brown.buttons .button.active,.ui.inverted.brown.buttons .button:active,.ui.inverted.brown.buttons .button:focus,.ui.inverted.brown.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.brown.button:hover,.ui.inverted.brown.buttons .button:hover{background-color:#b0620f}.ui.inverted.brown.button:focus,.ui.inverted.brown.buttons .button:focus{background-color:#c16808}.ui.inverted.brown.active.button,.ui.inverted.brown.buttons .active.button{background-color:#cc6f0d}.ui.inverted.brown.button:active,.ui.inverted.brown.buttons .button:active{background-color:#a96216}.ui.inverted.brown.basic.button,.ui.inverted.brown.basic.buttons .button,.ui.inverted.brown.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.brown.basic.button:hover,.ui.inverted.brown.basic.buttons .button:hover,.ui.inverted.brown.buttons .basic.button:hover{box-shadow:0 0 0 2px #b0620f inset;color:#d67c1c}.ui.inverted.brown.basic.button:focus,.ui.inverted.brown.basic.buttons .button:focus{box-shadow:0 0 0 2px #c16808 inset;color:#d67c1c}.ui.inverted.brown.basic.active.button,.ui.inverted.brown.basic.buttons .active.button,.ui.inverted.brown.buttons .basic.active.button{box-shadow:0 0 0 2px #cc6f0d inset;color:#d67c1c}.ui.inverted.brown.basic.button:active,.ui.inverted.brown.basic.buttons .button:active,.ui.inverted.brown.buttons .basic.button:active{box-shadow:0 0 0 2px #a96216 inset;color:#d67c1c}.ui.tertiary.brown.button,.ui.tertiary.brown.buttons .button,.ui.tertiary.brown.buttons .tertiary.button{background:0 0;box-shadow:none;color:#a5673f}.ui.tertiary.brown.button:hover,.ui.tertiary.brown.buttons .button:hover,.ui.tertiary.brown.buttons button:hover{box-shadow:inset 0 -.2em 0 #835f48;color:#835f48}.ui.tertiary.brown.button:focus,.ui.tertiary.brown.buttons .button:focus,.ui.tertiary.brown.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #7d573e;color:#7d573e}.ui.tertiary.brown.active.button,.ui.tertiary.brown.button:active,.ui.tertiary.brown.buttons .active.button,.ui.tertiary.brown.buttons .button:active,.ui.tertiary.brown.buttons .tertiary.active.button,.ui.tertiary.brown.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #ae561d;color:#995a31}.ui.grey.button,.ui.grey.buttons .button{background-color:#767676;color:#fff;text-shadow:none;background-image:none}.ui.grey.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.grey.button:hover,.ui.grey.buttons .button:hover{background-color:#838383;color:#fff;text-shadow:none}.ui.grey.button:focus,.ui.grey.buttons .button:focus{background-color:#8a8a8a;color:#fff;text-shadow:none}.ui.grey.button:active,.ui.grey.buttons .button:active{background-color:#909090;color:#fff;text-shadow:none}.ui.grey.active.button,.ui.grey.button .active.button:active,.ui.grey.buttons .active.button,.ui.grey.buttons .active.button:active{background-color:#696969;color:#fff;text-shadow:none}.ui.basic.grey.button,.ui.basic.grey.buttons .button{background:0 0;box-shadow:0 0 0 1px #767676 inset;color:#767676}.ui.basic.grey.button:hover,.ui.basic.grey.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #838383 inset;color:#838383}.ui.basic.grey.button:focus,.ui.basic.grey.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #8a8a8a inset;color:#838383}.ui.basic.grey.active.button,.ui.basic.grey.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #696969 inset;color:#909090}.ui.basic.grey.button:active,.ui.basic.grey.buttons .button:active{box-shadow:0 0 0 1px #909090 inset;color:#909090}.ui.inverted.grey.button,.ui.inverted.grey.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #d4d4d5 inset;color:#fff}.ui.inverted.grey.button.active,.ui.inverted.grey.button:active,.ui.inverted.grey.button:focus,.ui.inverted.grey.button:hover,.ui.inverted.grey.buttons .button.active,.ui.inverted.grey.buttons .button:active,.ui.inverted.grey.buttons .button:focus,.ui.inverted.grey.buttons .button:hover{box-shadow:none;color:rgba(0,0,0,.6)}.ui.inverted.grey.button:hover,.ui.inverted.grey.buttons .button:hover{background-color:#c2c4c5}.ui.inverted.grey.button:focus,.ui.inverted.grey.buttons .button:focus{background-color:#c7c9cb}.ui.inverted.grey.active.button,.ui.inverted.grey.buttons .active.button{background-color:#cfd0d2}.ui.inverted.grey.button:active,.ui.inverted.grey.buttons .button:active{background-color:#c2c4c5}.ui.inverted.grey.basic.button,.ui.inverted.grey.basic.buttons .button,.ui.inverted.grey.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.grey.basic.button:hover,.ui.inverted.grey.basic.buttons .button:hover,.ui.inverted.grey.buttons .basic.button:hover{box-shadow:0 0 0 2px #c2c4c5 inset;color:#fff}.ui.inverted.grey.basic.button:focus,.ui.inverted.grey.basic.buttons .button:focus{box-shadow:0 0 0 2px #c7c9cb inset;color:#dcddde}.ui.inverted.grey.basic.active.button,.ui.inverted.grey.basic.buttons .active.button,.ui.inverted.grey.buttons .basic.active.button{box-shadow:0 0 0 2px #cfd0d2 inset;color:#fff}.ui.inverted.grey.basic.button:active,.ui.inverted.grey.basic.buttons .button:active,.ui.inverted.grey.buttons .basic.button:active{box-shadow:0 0 0 2px #c2c4c5 inset;color:#fff}.ui.tertiary.grey.button,.ui.tertiary.grey.buttons .button,.ui.tertiary.grey.buttons .tertiary.button{background:0 0;box-shadow:none;color:#767676}.ui.tertiary.grey.button:hover,.ui.tertiary.grey.buttons .button:hover,.ui.tertiary.grey.buttons button:hover{box-shadow:inset 0 -.2em 0 #909090;color:#909090}.ui.tertiary.grey.button:focus,.ui.tertiary.grey.buttons .button:focus,.ui.tertiary.grey.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #9f9f9f;color:#9f9f9f}.ui.tertiary.grey.active.button,.ui.tertiary.grey.button:active,.ui.tertiary.grey.buttons .active.button,.ui.tertiary.grey.buttons .button:active,.ui.tertiary.grey.buttons .tertiary.active.button,.ui.tertiary.grey.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #5d5d5d;color:#696969}.ui.black.button,.ui.black.buttons .button{background-color:#1b1c1d;color:#fff;text-shadow:none;background-image:none}.ui.black.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.black.button:hover,.ui.black.buttons .button:hover{background-color:#27292a;color:#fff;text-shadow:none}.ui.black.button:focus,.ui.black.buttons .button:focus{background-color:#2f3032;color:#fff;text-shadow:none}.ui.black.button:active,.ui.black.buttons .button:active{background-color:#343637;color:#fff;text-shadow:none}.ui.black.active.button,.ui.black.button .active.button:active,.ui.black.buttons .active.button,.ui.black.buttons .active.button:active{background-color:#0f0f10;color:#fff;text-shadow:none}.ui.basic.black.button,.ui.basic.black.buttons .button{background:0 0;box-shadow:0 0 0 1px #1b1c1d inset;color:#1b1c1d}.ui.basic.black.button:hover,.ui.basic.black.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #27292a inset;color:#27292a}.ui.basic.black.button:focus,.ui.basic.black.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #2f3032 inset;color:#27292a}.ui.basic.black.active.button,.ui.basic.black.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #0f0f10 inset;color:#343637}.ui.basic.black.button:active,.ui.basic.black.buttons .button:active{box-shadow:0 0 0 1px #343637 inset;color:#343637}.ui.inverted.black.button,.ui.inverted.black.buttons .button{background-color:transparent;box-shadow:0 0 0 2px #d4d4d5 inset;color:#fff}.ui.inverted.black.button.active,.ui.inverted.black.button:active,.ui.inverted.black.button:focus,.ui.inverted.black.button:hover,.ui.inverted.black.buttons .button.active,.ui.inverted.black.buttons .button:active,.ui.inverted.black.buttons .button:focus,.ui.inverted.black.buttons .button:hover{box-shadow:none;color:#fff}.ui.inverted.black.button:hover,.ui.inverted.black.buttons .button:hover{background-color:#000}.ui.inverted.black.button:focus,.ui.inverted.black.buttons .button:focus{background-color:#000}.ui.inverted.black.active.button,.ui.inverted.black.buttons .active.button{background-color:#000}.ui.inverted.black.button:active,.ui.inverted.black.buttons .button:active{background-color:#000}.ui.inverted.black.basic.button,.ui.inverted.black.basic.buttons .button,.ui.inverted.black.buttons .basic.button{background-color:transparent;box-shadow:0 0 0 2px rgba(255,255,255,.5) inset;color:#fff}.ui.inverted.black.basic.button:hover,.ui.inverted.black.basic.buttons .button:hover,.ui.inverted.black.buttons .basic.button:hover{box-shadow:0 0 0 2px #000 inset;color:#fff}.ui.inverted.black.basic.button:focus,.ui.inverted.black.basic.buttons .button:focus{box-shadow:0 0 0 2px #000 inset;color:#545454}.ui.inverted.black.basic.active.button,.ui.inverted.black.basic.buttons .active.button,.ui.inverted.black.buttons .basic.active.button{box-shadow:0 0 0 2px #000 inset;color:#fff}.ui.inverted.black.basic.button:active,.ui.inverted.black.basic.buttons .button:active,.ui.inverted.black.buttons .basic.button:active{box-shadow:0 0 0 2px #000 inset;color:#fff}.ui.tertiary.black.button,.ui.tertiary.black.buttons .button,.ui.tertiary.black.buttons .tertiary.button{background:0 0;box-shadow:none;color:#1b1c1d}.ui.tertiary.black.button:hover,.ui.tertiary.black.buttons .button:hover,.ui.tertiary.black.buttons button:hover{box-shadow:inset 0 -.2em 0 #8b8f93;color:#8b8f93}.ui.tertiary.black.button:focus,.ui.tertiary.black.buttons .button:focus,.ui.tertiary.black.buttons .tertiary.button:focus{box-shadow:inset 0 -.2em 0 #93969a;color:#93969a}.ui.tertiary.black.active.button,.ui.tertiary.black.button:active,.ui.tertiary.black.buttons .active.button,.ui.tertiary.black.buttons .button:active,.ui.tertiary.black.buttons .tertiary.active.button,.ui.tertiary.black.buttons .tertiary.button:active{box-shadow:inset 0 -.2em 0 #404245;color:#0f0f10}.ui.positive.button,.ui.positive.buttons .button{background-color:#21ba45;color:#fff;text-shadow:none;background-image:none}.ui.positive.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.positive.button:hover,.ui.positive.buttons .button:hover{background-color:#16ab39;color:#fff;text-shadow:none}.ui.positive.button:focus,.ui.positive.buttons .button:focus{background-color:#0ea432;color:#fff;text-shadow:none}.ui.positive.button:active,.ui.positive.buttons .button:active{background-color:#198f35;color:#fff;text-shadow:none}.ui.positive.active.button,.ui.positive.button .active.button:active,.ui.positive.buttons .active.button,.ui.positive.buttons .active.button:active{background-color:#13ae38;color:#fff;text-shadow:none}.ui.basic.positive.button,.ui.basic.positive.buttons .button{background:0 0;box-shadow:0 0 0 1px #21ba45 inset;color:#21ba45}.ui.basic.positive.button:hover,.ui.basic.positive.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #16ab39 inset;color:#16ab39}.ui.basic.positive.button:focus,.ui.basic.positive.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #0ea432 inset;color:#16ab39}.ui.basic.positive.active.button,.ui.basic.positive.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #13ae38 inset;color:#198f35}.ui.basic.positive.button:active,.ui.basic.positive.buttons .button:active{box-shadow:0 0 0 1px #198f35 inset;color:#198f35}.ui.buttons:not(.vertical)>.basic.positive.button:not(:first-child){margin-left:-1px}.ui.negative.button,.ui.negative.buttons .button{background-color:#db2828;color:#fff;text-shadow:none;background-image:none}.ui.negative.button{box-shadow:0 0 0 0 rgba(34,36,38,.15) inset}.ui.negative.button:hover,.ui.negative.buttons .button:hover{background-color:#d01919;color:#fff;text-shadow:none}.ui.negative.button:focus,.ui.negative.buttons .button:focus{background-color:#ca1010;color:#fff;text-shadow:none}.ui.negative.button:active,.ui.negative.buttons .button:active{background-color:#b21e1e;color:#fff;text-shadow:none}.ui.negative.active.button,.ui.negative.button .active.button:active,.ui.negative.buttons .active.button,.ui.negative.buttons .active.button:active{background-color:#d41515;color:#fff;text-shadow:none}.ui.basic.negative.button,.ui.basic.negative.buttons .button{background:0 0;box-shadow:0 0 0 1px #db2828 inset;color:#db2828}.ui.basic.negative.button:hover,.ui.basic.negative.buttons .button:hover{background:0 0;box-shadow:0 0 0 1px #d01919 inset;color:#d01919}.ui.basic.negative.button:focus,.ui.basic.negative.buttons .button:focus{background:0 0;box-shadow:0 0 0 1px #ca1010 inset;color:#d01919}.ui.basic.negative.active.button,.ui.basic.negative.buttons .active.button{background:0 0;box-shadow:0 0 0 1px #d41515 inset;color:#b21e1e}.ui.basic.negative.button:active,.ui.basic.negative.buttons .button:active{box-shadow:0 0 0 1px #b21e1e inset;color:#b21e1e}.ui.buttons:not(.vertical)>.basic.negative.button:not(:first-child){margin-left:-1px}.ui.buttons{display:inline-flex;flex-direction:row;font-size:0;vertical-align:baseline;margin:0 .25em 0 0}.ui.buttons:not(.basic):not(.inverted){box-shadow:none}.ui.buttons::after{content:".";display:block;height:0;clear:both;visibility:hidden}.ui.buttons .button{flex:1 0 auto;border-radius:0;margin:0}.ui.buttons:not(.basic):not(.inverted)>.button:not(.basic):not(.inverted){box-shadow:0 0 0 1px transparent inset,0 0 0 0 rgba(34,36,38,.15) inset}.ui.buttons .button:first-child{border-left:none;margin-left:0;border-top-left-radius:.28571429rem;border-bottom-left-radius:.28571429rem}.ui.buttons .button:last-child{border-top-right-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.buttons{display:inline-flex;flex-direction:column}.ui.vertical.buttons .button{display:block;float:none;width:100%;margin:0;border-radius:0}.ui.vertical.buttons .button:not(.basic){box-shadow:none}.ui.vertical.buttons .button:first-child{border-top-left-radius:.28571429rem;border-top-right-radius:.28571429rem}.ui.vertical.buttons .button:last-child{margin-bottom:0;border-bottom-left-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.vertical.buttons .button:only-child{border-radius:.28571429rem}.ui.vertical.buttons .basic.button:not(:first-child){border-top:none}.ui.wrapping.buttons{flex-wrap:wrap}.ui.wrapping.basic.buttons{border-bottom:none}.ui.wrapping.basic.buttons .button{border-bottom:1px solid rgba(34,36,38,.15)}.ui.wrapping.basic.buttons .button:hover{background:0 0!important}.ui.compact.wrapping.buttons .button{flex:none}.ui.wrapped.buttons:not(.spaced){border-top-right-radius:0}.ui.wrapped.buttons:not(.spaced) .button:first-child{border-radius:.28571429rem 0 0 0}.ui.wrapped.buttons:not(.spaced) .button:last-child{border-radius:0 0 .28571429rem 0}.ui.wrapped[class*="top attached"].buttons{border-radius:.28571429rem 0 0 0}.ui.wrapped[class*="top attached"].buttons .button:last-child{border-radius:0}.ui.wrapped[class*="bottom attached"].buttons{border-radius:0 0 0 .28571429rem}.ui.wrapped[class*="bottom attached"].buttons .button:first-child{border-radius:0}.ui.spaced.buttons .ui.button{margin-bottom:1em;margin-right:1em;border-radius:.28571429rem}.ui.spaced.basic.buttons{border:none}.ui.spaced.basic.buttons .button{border:1px solid rgba(34,36,38,.15)}.ui.spaced.basic.buttons .button.basic{border:none}.ui.spaced.basic.vertical.buttons .button:first-child{border-top:1px solid rgba(34,36,38,.15)}.ui.spaced.basic.wrapping.buttons .button:not(.basic){border-top:1px solid rgba(34,36,38,.15);border-right:1px solid rgba(34,36,38,.15)}.ui.spaced.basic.wrapping.buttons .button:not(.basic):first-child{border-left:1px solid rgba(34,36,38,.15)}.ui.spaced.basic.inverted.buttons .basic.button{margin-bottom:calc(1em + 1px);margin-top:1px}.ui.basic.buttons:not(.vertical) .basic.button,.ui.basic.buttons:not(.vertical).inverted .button{margin-left:-1px;border-right:none}.ui.basic.buttons:not(.vertical):not(.spaced):not(.inverted) .basic.button{margin-top:-1px;border-bottom:none}.ui.attached.basic.buttons:not(.wrapping):not(.inverted) .basic.button,.ui.inverted.basic.buttons:not(.spaced) .button{margin-bottom:-1px}.ui.basic.buttons:not(.vertical):not(.attached):not(.spaced):not(.wrapping):not(.inverted) .basic.button{margin-bottom:-1px} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.css b/internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.css new file mode 100755 index 0000000..5091c47 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.css @@ -0,0 +1,9 @@ +/*! + * # Fomantic-UI 2.9.3 - Calendar + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */.ui.calendar.popup{max-width:none;padding:0;border:none;-webkit-user-select:none;-ms-user-select:none;user-select:none}.ui.calendar.popup.inverted::before{background:#2b2b2b}.ui.calendar .calendar:focus,.ui.calendar.popup:focus{outline:0}.ui.calendar.popup .ui.grid{display:block;white-space:nowrap}.ui.calendar.popup .ui.grid>.column{width:auto}.ui.calendar .ui.table.minute,.ui.calendar .ui.table.month,.ui.calendar .ui.table.year{min-width:15em}.ui.calendar .ui.table.day{min-width:18em}.ui.calendar .ui.table.day.andweek{min-width:22em}.ui.calendar .ui.table.hour{min-width:20em}.ui.calendar .ui.table tr td,.ui.calendar .ui.table tr th{padding:.5em;white-space:nowrap}.ui.calendar .ui.table tr th{border-left:none}.ui.calendar .ui.table tr th i.icon{margin:0}.ui.calendar .ui.table tr:first-child th{position:relative;padding-left:0;padding-right:0}.ui.calendar .ui.table.day tr:first-child th{border:none}.ui.calendar .ui.table.day tr:nth-child(2) th{padding-top:.2em;padding-bottom:.3em}.ui.calendar .ui.table tr td{padding-left:.1em;padding-right:.1em}.ui.calendar .ui.table tr .link{cursor:pointer}.ui.calendar .ui.table tr .prev.link{width:14.28571429%;position:absolute;left:0}.ui.calendar .ui.table tr .next.link{width:14.28571429%;position:absolute;right:0}.ui.ui.calendar .ui.table tr .disabled{pointer-events:auto;cursor:default;color:rgba(40,40,40,.3)}.ui.calendar .ui.table tr .adjacent:not(.disabled):not(.active){color:rgba(0,0,0,.6);background:rgba(0,0,0,.03)}.ui.calendar .ui.table tr td.today{font-weight:700}.ui.calendar .ui.table tr td.range{background:rgba(0,0,0,.05);color:rgba(0,0,0,.95);box-shadow:none}.ui.calendar:not(.disabled).popup.active .ui.table tbody tr td.focus,.ui.calendar:not(.disabled):focus .ui.table tbody tr td.focus{box-shadow:inset 0 0 0 1px #85b7d9}.ui.inverted.calendar .ui.table.inverted tr td.range{background:rgba(255,255,255,.08);color:#fff;box-shadow:none}.ui.inverted.calendar:not(.disabled) .calendar:focus .ui.table.inverted tbody tr td.focus,.ui.inverted.calendar:not(.disabled).popup.active .ui.table.inverted tbody tr td.focus{box-shadow:inset 0 0 0 1px #85b7d9}.ui.inverted.calendar .ui.ui.ui.inverted.table tr .disabled{color:rgba(225,225,225,.3)}.ui.inverted.calendar .ui.inverted.table tr .adjacent:not(.disabled):not(.active){color:rgba(255,255,255,.8);background:rgba(255,255,255,.02)}.ui.ui.ui.calendar.popup>.ui.ui.grid{margin:-1rem}.ui.ui.ui.calendar.popup>.ui.ui.grid>.column:not(:first-child){padding-left:0}.ui.ui.ui.calendar.popup>.ui.ui.grid>.column:not(:first-child)>.ui.table{border-top-left-radius:0;border-bottom-left-radius:0}.ui.ui.ui.calendar.popup>.ui.ui.grid>.column:not(:last-child){padding-right:0}.ui.ui.ui.calendar.popup>.ui.ui.grid>.column:not(:last-child)>.ui.table{border-top-right-radius:0;border-bottom-right-radius:0}.ui.mini.calendar,.ui.mini.calendar .ui.table tr td,.ui.mini.calendar .ui.table tr th{font-size:.78571429rem}.ui.mini.calendar .ui.table.minute,.ui.mini.calendar .ui.table.month,.ui.mini.calendar .ui.table.year{min-width:11.78571429em}.ui.mini.calendar .ui.table.day{min-width:14.14285714em}.ui.mini.calendar .ui.table.day.andweek{min-width:17.28571429em}.ui.mini.calendar .ui.table.hour{min-width:15.71428571em}.ui.tiny.calendar,.ui.tiny.calendar .ui.table tr td,.ui.tiny.calendar .ui.table tr th{font-size:.85714286rem}.ui.tiny.calendar .ui.table.minute,.ui.tiny.calendar .ui.table.month,.ui.tiny.calendar .ui.table.year{min-width:12.85714286em}.ui.tiny.calendar .ui.table.day{min-width:15.42857143em}.ui.tiny.calendar .ui.table.day.andweek{min-width:18.85714286em}.ui.tiny.calendar .ui.table.hour{min-width:17.14285714em}.ui.small.calendar,.ui.small.calendar .ui.table tr td,.ui.small.calendar .ui.table tr th{font-size:.92857143rem}.ui.small.calendar .ui.table.minute,.ui.small.calendar .ui.table.month,.ui.small.calendar .ui.table.year{min-width:13.92857143em}.ui.small.calendar .ui.table.day{min-width:16.71428571em}.ui.small.calendar .ui.table.day.andweek{min-width:20.42857143em}.ui.small.calendar .ui.table.hour{min-width:18.57142857em}.ui.large.calendar,.ui.large.calendar .ui.table tr td,.ui.large.calendar .ui.table tr th{font-size:1.14285714rem}.ui.large.calendar .ui.table.minute,.ui.large.calendar .ui.table.month,.ui.large.calendar .ui.table.year{min-width:17.14285714em}.ui.large.calendar .ui.table.day{min-width:20.57142857em}.ui.large.calendar .ui.table.day.andweek{min-width:25.14285714em}.ui.large.calendar .ui.table.hour{min-width:22.85714286em}.ui.big.calendar,.ui.big.calendar .ui.table tr td,.ui.big.calendar .ui.table tr th{font-size:1.28571429rem}.ui.big.calendar .ui.table.minute,.ui.big.calendar .ui.table.month,.ui.big.calendar .ui.table.year{min-width:19.28571429em}.ui.big.calendar .ui.table.day{min-width:23.14285714em}.ui.big.calendar .ui.table.day.andweek{min-width:28.28571429em}.ui.big.calendar .ui.table.hour{min-width:25.71428571em}.ui.huge.calendar,.ui.huge.calendar .ui.table tr td,.ui.huge.calendar .ui.table tr th{font-size:1.42857143rem}.ui.huge.calendar .ui.table.minute,.ui.huge.calendar .ui.table.month,.ui.huge.calendar .ui.table.year{min-width:21.42857143em}.ui.huge.calendar .ui.table.day{min-width:25.71428571em}.ui.huge.calendar .ui.table.day.andweek{min-width:31.42857143em}.ui.huge.calendar .ui.table.hour{min-width:28.57142857em}.ui.massive.calendar,.ui.massive.calendar .ui.table tr td,.ui.massive.calendar .ui.table tr th{font-size:1.71428571rem}.ui.massive.calendar .ui.table.minute,.ui.massive.calendar .ui.table.month,.ui.massive.calendar .ui.table.year{min-width:25.71428571em}.ui.massive.calendar .ui.table.day{min-width:30.85714286em}.ui.massive.calendar .ui.table.day.andweek{min-width:37.71428571em}.ui.massive.calendar .ui.table.hour{min-width:34.28571429em}.ui.disabled.calendar{opacity:.45}.ui.disabled.calendar .ui.table tr .link,.ui.disabled.calendar>.input{pointer-events:none} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.js b/internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.js new file mode 100755 index 0000000..e88d314 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/calendar.min.js @@ -0,0 +1,11 @@ +/* + * # Fomantic UI - 2.9.3 + * https://github.com/fomantic/Fomantic-UI + * https://fomantic-ui.com/ + * + * Copyright 2023 Contributors + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */ +!function(oe,x,T){"use strict";x=void 0!==x&&x.Math===Math?x:globalThis,oe.fn.calendar=function(m){var g,e=oe(this),y=oe(T),D=Date.now(),v=[],b=m,M="string"==typeof b,C=[].slice.call(arguments,1),w={5:{row:4,column:3},10:{row:3,column:2},15:{row:2,column:2},20:{row:3,column:1},30:{row:2,column:1}},re=["","one","two","three","four","five","six","seven","eight"];return e.each(function(){var p,e,z=oe.isPlainObject(m)?oe.extend(!0,{},oe.fn.calendar.settings,m):oe.extend({},oe.fn.calendar.settings),_=z.className,a=z.namespace,n=z.selector,Q=z.formatter,Z=z.parser,X=z.metadata,ee=w[z.minTimeGap],l=z.error,t="."+a,r="module-"+a,o=oe(this),i=o.find(n.input),s=o.find(n.activator),d=this,u=o.data(r),te=u&&u.popupId?y.find("#"+u.popupId):o.find(n.popup),c=!1,ae=o.hasClass(_.inverted),f=!1,h=!1,ne={initialize:function(){ne.debug("Initializing calendar for",d,o),p=ne.get.isTouch(),ne.setup.config(),ne.setup.popup(),ne.setup.inline(),ne.setup.input(),ne.setup.date(),ne.create.calendar(),ne.bind.events(),ne.observeChanges(),ne.instantiate()},instantiate:function(){ne.verbose("Storing instance of calendar"),u=ne,o.data(r,u)},destroy:function(){ne.verbose("Destroying previous calendar for",d),o.removeData(r),ne.unbind.events(),ne.disconnect.classObserver()},setup:{config:function(){null!==ne.get.minDate()&&ne.set.minDate(o.data(X.minDate)),null!==ne.get.maxDate()&&ne.set.maxDate(o.data(X.maxDate)),ne.setting("type",ne.get.type()),ne.setting("on",z.on||"click")},popup:function(){var e,t;z.inline||0===s.length&&0===(s=o.children().first()).length||(void 0===oe.fn.popup?ne.error(l.popup):((te=0===te.length?z.context?(ne.popupId=a+"_popup_"+(Math.random().toString(16)+"000000000").slice(2,10),oe("
",{id:ne.popupId}).addClass(_.popup).appendTo(y.find(z.context))):(e=0<(t=s.parent()).closest(n.append).length?"appendTo":"prependTo",oe("
").addClass(_.popup)[e](t)):te).addClass(_.calendar),ae&&te.addClass(_.inverted),e=function(){return ne.refreshTooltips(),z.onVisible.apply(te,arguments)},0===i.length&&(te.attr("tabindex","0"),e=function(){return ne.refreshTooltips(),ne.focus(),z.onVisible.apply(te,arguments)}),t=ne.setting("on"),t=oe.extend({},z.popupOptions,{popup:te,movePopup:!z.context,on:t,hoverable:"hover"===t,closable:"click"===t,onShow:function(){return ne.set.focusDate(ne.get.date()),ne.set.mode(ne.get.validatedMode(z.startMode)),z.onShow.apply(te,arguments)},onVisible:e,onHide:z.onHide,onHidden:function(){return ne.blur(),z.onHidden.apply(te,arguments)}}),ne.popup(t)))},inline:function(){0").addClass(_.calendar).appendTo(o),0===i.length&&te.attr("tabindex","0"))},input:function(){z.touchReadonly&&0").addClass(_.grid).appendTo(D)),t=0;t").addClass(_.column).appendTo(j));var D,v=G+t,B=(new Date(h,v,1).getDay()-z.firstDayOfWeek%7+7)%7,b=(!z.constantHeight&&l&&(b=new Date(h,v+1,0).getDate()+B,P=Math.ceil(b/7)),i?10:s?1:0),M=l?1:0,C=d||u?1:0,w=d||u?f:1,x=new Date(h-b,v-M,w-C,c),M=new Date(h+b,v+M,w+C,c),w=i?new Date(10*Math.ceil(h/10)-9,0,0):s?new Date(h,0,0):l?new Date(h,v,0):new Date(h,v,f,-1),C=i?new Date(10*Math.ceil(h/10)+1,0,1):s?new Date(h+1,0,1):l?new Date(h,v+1,1):new Date(h,v,f+1),T=a,T=(l&&z.showWeekNumbers&&(T+=" andweek"),oe("").addClass(_.table).addClass(T).addClass(re[m]+" column").appendTo(D)),K=(ae&&T.addClass(_.inverted),m);if(!W){var U=oe("").appendTo(T),Y=oe("").appendTo(U),k=oe("").appendTo(U),z.showWeekNumbers&&((k=oe("").appendTo(T),N=i?10*Math.ceil(h/10)-9:l?1-B:0,L=0;L").appendTo(J),l&&z.showWeekNumbers&&((k=oe("").appendTo(J),(w=oe("
").attr("colspan",""+m).appendTo(Y),O=i||s?new Date(h,0,1):l?new Date(h,v,1):new Date(h,v,f,c,p),A=oe("").addClass(_.link).appendTo(k),O=(A.text(ne.helper.dateFormat(Q[a+"Header"],O)),s?z.disableYear?"day":"year":l?z.disableMonth?"year":"month":"day");if(A.data(X.mode,O),0===t&&((A=oe("").addClass(_.prev).appendTo(k)).data(X.focusDate,x),A.toggleClass(_.disabledCell,!ne.helper.isDateInRange(w,a)),oe("").addClass(_.prevIcon).appendTo(A)),t===g-1&&((O=oe("").addClass(_.next).appendTo(k)).data(X.focusDate,M),O.toggleClass(_.disabledCell,!ne.helper.isDateInRange(C,a)),oe("").addClass(_.nextIcon).appendTo(O)),l)for(Y=oe("
").appendTo(Y)).text(z.text.weekNo),k.addClass(_.weekCell),K--),N=0;N").appendTo(Y)).text(Q.dayColumnHeader((N+z.firstDayOfWeek)%7,z))}for(var J=oe("
").appendTo(Y)).text(ne.get.weekOfYear(h,v,N+1-z.firstDayOfWeek)),k.addClass(_.weekCell)),e=0;e").addClass(_.cell).appendTo(Y)).text(E),k.data(X.date,H),l&&H.getMonth()!==(v+12)%12),I=!z.selectAdjacentDays&&E||!ne.helper.isDateInRange(H,a)||z.isDisabled(H,a)||ne.helper.isDisabled(H,a)||!ne.helper.isEnabled(H,a),S=(I?(null!==(S=ne.helper.findDayAsObject(H,a,z.disabledDates))&&S[X.message]&&(k.attr("data-tooltip",S[X.message]),k.attr("data-position",S[X.position]||y),(S[X.inverted]||ae&&void 0===S[X.inverted])&&k.attr("data-inverted",""),S[X.variation]&&k.attr("data-variation",S[X.variation])),"hour"===a&&null!==(S=ne.helper.findHourAsObject(H,a,z.disabledHours))&&S[X.message]&&(k.attr("data-tooltip",S[X.message]),k.attr("data-position",S[X.position]||y),(S[X.inverted]||ae&&void 0===S[X.inverted])&&k.attr("data-inverted",""),S[X.variation]&&k.attr("data-variation",S[X.variation]))):null!==(F=ne.helper.findDayAsObject(H,a,z.eventDates))&&(k.addClass(F[X.class]||z.eventClass),F[X.message]&&(k.attr("data-tooltip",F[X.message]),k.attr("data-position",F[X.position]||y),(F[X.inverted]||ae&&void 0===F[X.inverted])&&k.attr("data-inverted",""),F[X.variation]&&k.attr("data-variation",F[X.variation]))),ne.helper.dateEqual(H,q,a)),$=ne.helper.dateEqual(H,n,a),E=(k.toggleClass(_.adjacentCell,E&&!F),k.toggleClass(_.disabledCell,I),k.toggleClass(_.activeCell,S&&!(E&&I)),d||u||k.toggleClass(_.todayCell,!E&&$),{mode:a,adjacent:E,disabled:I,active:S,today:$});Q.cell(k,H,E),ne.helper.dateEqual(H,r,a)&&ne.set.focusDate(H,!1,!1)}z.today&&(x=oe("
").attr("colspan",""+m).addClass(_.today).appendTo(x)).text(Q.today(z)),w.data(X.date,n)),ne.update.focus(!1,T),z.inline&&ne.refreshTooltips()}}},update:{focus:function(e,t){t=t||te;var i=ne.get.mode(),a=ne.get.date(),s=ne.get.focusDate(),l=ne.get.startDate(),d=ne.get.endDate(),u=(e?s:null)||a||(p?null:s);t.find("td").each(function(){var e,t,a,n,r=oe(this),o=r.data(X.date);o&&(e=r.hasClass(_.disabledCell),t=r.hasClass(_.activeCell),a=r.hasClass(_.adjacentCell),n=ne.helper.dateEqual(o,s,i),o=!!u&&(!!l&&ne.helper.isDateInRange(o,i,l,u)||!!d&&ne.helper.isDateInRange(o,i,u,d)),r.toggleClass(_.focusCell,n&&(!p||c)&&(!a||z.selectAdjacentDays&&a)&&!e),ne.helper.isTodayButton(r)||r.toggleClass(_.rangeCell,o&&!t&&!e))})}},refresh:function(){ne.create.calendar()},refreshTooltips:function(){var n=oe(x).width();te.find("td[data-position]").each(function(){var e=oe(this),t=x.getComputedStyle(e[0],"::after").width.replace(/[^\d.]/g,""),a=e.attr("data-position"),t=n-e.width()-(parseInt(t,10)||250)>e.offset().left?"right":"left";-1===a.indexOf(t)&&e.attr("data-position",a.replace(/(left|right)/,t))})},bind:{events:function(){ne.debug("Binding events"),te.on("mousedown"+t,ne.event.mousedown),te.on("touchstart"+t,ne.event.mousedown),te.on("mouseup"+t,ne.event.mouseup),te.on("touchend"+t,ne.event.mouseup),te.on("mouseover"+t,ne.event.mouseover),0=e?ne.verbose("Unable to set maxDate variable lower that minDate variable",e,z.minDate):(ne.setting("maxDate",e),ne.set.dataKeyValue(X.maxDate,e))},monthOffset:function(e,t){var a=Math.max(z.multiMonth,1);e=Math.max(1-a,Math.min(0,e)),ne.set.dataKeyValue(X.monthOffset,e,t)},mode:function(e,t){ne.set.dataKeyValue(X.mode,e,t)},dataKeyValue:function(e,t,a){var n=o.data(e),n=n===t||n<=t&&t<=n;return t?o.data(e,t):o.removeData(e),(a=!1!==a&&!n)&&ne.refresh(),!n}},selectDate:function(e,t){ne.verbose("New date selection",e);var a=ne.get.mode();t||"minute"===a||z.disableMinute&&"hour"===a||"date"===z.type&&"day"===a||"month"===z.type&&"month"===a||"year"===z.type&&"year"===a?!1!==ne.set.date(e)&&(h=!0,z.closable&&(ne.popup("hide"),(t=ne.get.calendarModule(z.endCalendar))&&(t.refresh(),"focus"!==t.setting("on")&&t.popup("show"),t.focus()))):(t="year"===a?z.disableMonth?"day":"month":"month"===a?"day":"day"===a?"hour":"minute",ne.set.mode(t),"hour"===a||"day"===a&&ne.get.date()?ne.set.date(e,!0,!1):ne.set.focusDate(e))},changeDate:function(e){ne.set.date(e)},clear:function(){ne.set.date()},popup:function(){return s.popup.apply(s,arguments)},focus:function(){(0=t.centuryBreak&&a===y.length-1){n<=99&&(n+=t.currentCentury-100),h=n,y.splice(a,1);break}if(f<0)for(a=0;a.card{max-width:100%;position:relative;display:flex;flex-direction:column;width:290px;min-height:0;background:#fff;padding:0;border:none;border-radius:.28571429rem;box-shadow:0 1px 3px 0 #d4d4d5,0 0 0 1px #d4d4d5;transition:box-shadow .1s ease,transform .1s ease;z-index:"";word-wrap:break-word}.ui.card{margin:1em 0}.ui.card a,.ui.cards>.card a{cursor:pointer}.ui.card:first-child{margin-top:0}.ui.card:last-child{margin-bottom:0}.ui.cards{display:flex;margin:-.875em -.5em;flex-wrap:wrap}.ui.cards>.card{display:flex;margin:.875em .5em;float:none}.ui.card::after,.ui.cards::after{display:block;content:" ";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.cards~.ui.cards{margin-top:.875em}.ui.card>:first-child,.ui.cards>.card>:first-child{border-radius:.28571429rem .28571429rem 0 0!important;border-top:none!important}.ui.card>:last-child,.ui.cards>.card>:last-child{border-radius:0 0 .28571429rem .28571429rem!important}.ui.card>:only-child,.ui.cards>.card>:only-child{border-radius:.28571429rem!important}.ui.card>.image,.ui.cards>.card>.image{position:relative;display:block;flex:0 0 auto;padding:0;background:rgba(0,0,0,.05)}.ui.card>.image>img,.ui.cards>.card>.image>img{display:block;width:100%;height:auto;border-radius:inherit}.ui.card>.image:not(.ui)>img,.ui.cards>.card>.image:not(.ui)>img{border:none}.ui.card>.content,.ui.cards>.card>.content{flex-grow:1;border:none;border-top:1px solid rgba(34,36,38,.1);background:0 0;margin:0;padding:1em;box-shadow:none;font-size:1em;border-radius:0}.ui.card>.content::after,.ui.cards>.card>.content::after{display:block;content:" ";height:0;clear:both;overflow:hidden;visibility:hidden}.ui.card>.content>.header,.ui.cards>.card>.content>.header{display:block;margin:"";font-family:Lato,system-ui,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";color:rgba(0,0,0,.85)}.ui.card>.content>.header:not(.ui),.ui.cards>.card>.content>.header:not(.ui){font-weight:700;font-size:1.28571429em;margin-top:-.21425em;line-height:1.28571429em}.ui.card>.content>.header+.description,.ui.card>.content>.meta+.description,.ui.cards>.card>.content>.header+.description,.ui.cards>.card>.content>.meta+.description{margin-top:.5em}.ui.card [class*="left floated"],.ui.cards>.card [class*="left floated"]{float:left}.ui.card [class*="right floated"],.ui.cards>.card [class*="right floated"]{float:right}.ui.card [class*="left aligned"],.ui.cards>.card [class*="left aligned"]{text-align:left}.ui.card [class*="center aligned"],.ui.cards>.card [class*="center aligned"]{text-align:center}.ui.card [class*="right aligned"],.ui.cards>.card [class*="right aligned"]{text-align:right}.ui.card .content img,.ui.cards>.card .content img{display:inline-block;vertical-align:middle;width:""}.ui.card .avatar img,.ui.card img.avatar,.ui.cards>.card .avatar img,.ui.cards>.card img.avatar{width:2em;height:2em;border-radius:500rem}.ui.card>.content>.description,.ui.cards>.card>.content>.description{clear:both;color:rgba(0,0,0,.68)}.ui.card>.content p,.ui.cards>.card>.content p{margin:0 0 .5em}.ui.card>.content p:last-child,.ui.cards>.card>.content p:last-child{margin-bottom:0}.ui.card .meta,.ui.cards>.card .meta{font-size:1em;color:rgba(0,0,0,.4)}.ui.card .meta *,.ui.cards>.card .meta *{margin-right:.3em}.ui.card .meta :last-child,.ui.cards>.card .meta :last-child{margin-right:0}.ui.card .meta [class*="right floated"],.ui.cards>.card .meta [class*="right floated"]{margin-right:0;margin-left:.3em}.ui.card>.content a:not(.ui),.ui.cards>.card>.content a:not(.ui){color:"";transition:color .1s ease}.ui.card>.content a:not(.ui):hover,.ui.cards>.card>.content a:not(.ui):hover{color:""}.ui.card>.content>a.header,.ui.cards>.card>.content>a.header{color:rgba(0,0,0,.85)}.ui.card>.content>a.header:hover,.ui.cards>.card>.content>a.header:hover{color:#1e70bf}.ui.card .meta>a:not(.ui),.ui.cards>.card .meta>a:not(.ui){color:rgba(0,0,0,.4)}.ui.card .meta>a:not(.ui):hover,.ui.cards>.card .meta>a:not(.ui):hover{color:rgba(0,0,0,.87)}.ui.card>.button,.ui.card>.buttons,.ui.cards>.card>.button,.ui.cards>.card>.buttons{margin:0 -1px;width:calc(100% + 2px)}.ui.card>.button:last-child,.ui.card>.buttons:last-child,.ui.cards>.card>.button:last-child,.ui.cards>.card>.buttons:last-child{margin-bottom:-1px}.ui.cards:not(.raised)>.basic.card:not(.raised),.ui.ui.ui.basic.card:not(.raised),.ui.ui.ui.basic.cards:not(.raised)>.card:not(.raised){box-shadow:none}.ui.cards:not(.raised)>.basic.card:not(.raised)>.button,.ui.cards:not(.raised)>.basic.card:not(.raised)>.buttons,.ui.ui.ui.basic.card:not(.raised)>.button,.ui.ui.ui.basic.card:not(.raised)>.buttons,.ui.ui.ui.basic.cards:not(.raised)>.card:not(.raised)>.button,.ui.ui.ui.basic.cards:not(.raised)>.card:not(.raised)>.buttons{margin:0;width:100%}.ui.ui.ui.ui.ui.basic.card:not(.raised):hover,.ui.ui.ui.ui.ui.basic.cards:not(.raised) .card:not(.raised):hover{box-shadow:none}.ui.card .dimmer,.ui.cards>.card .dimmer{background:"";z-index:10}.ui.card>.content .star.icon,.ui.cards>.card>.content .star.icon{cursor:pointer;opacity:.75;transition:color .1s ease}.ui.card>.content .star.icon:hover,.ui.cards>.card>.content .star.icon:hover{opacity:1;color:#ffb70a}.ui.card>.content .active.star.icon,.ui.cards>.card>.content .active.star.icon{color:#ffe623}.ui.card>.content .like.icon,.ui.cards>.card>.content .like.icon{cursor:pointer;opacity:.75;transition:color .1s ease}.ui.card>.content .like.icon:hover,.ui.cards>.card>.content .like.icon:hover{opacity:1;color:#ff2733}.ui.card>.content .active.like.icon,.ui.cards>.card>.content .active.like.icon{color:#ff2733}.ui.card>.extra,.ui.cards>.card>.extra{max-width:100%;min-height:0!important;flex-grow:0;border-top:1px solid rgba(0,0,0,.05)!important;position:static;background:0 0;width:auto;margin:0;padding:.75em 1em;top:0;left:0;color:rgba(0,0,0,.4);box-shadow:none;transition:color .1s ease}.ui.card>.extra a:not(.ui),.ui.cards>.card>.extra a:not(.ui){color:rgba(0,0,0,.4)}.ui.card>.extra a:not(.ui):hover,.ui.cards>.card>.extra a:not(.ui):hover{color:#1e70bf}.ui.disabled.card{opacity:.45;color:rgba(40,40,40,.3);pointer-events:none}.ui.loading.card{position:relative;cursor:default;pointer-events:none;transition:all 0s linear}.ui.loading.card::before{position:absolute;content:"";top:0;left:0;background:rgba(255,255,255,.8);width:100%;height:100%;border-radius:.28571429rem;z-index:100}.ui.loading.card::after{position:absolute;content:"";top:50%;left:50%;margin:-1.5em 0 0 -1.5em;width:3em;height:3em;animation:loader .6s infinite linear;border:.2em solid #767676;border-radius:500rem;box-shadow:0 0 0 1px transparent;visibility:visible;z-index:101}.ui.card.horizontal,.ui.horizontal.cards>.card{flex-flow:row wrap;min-width:270px;width:400px;max-width:100%}.ui.card.horizontal>.image,.ui.horizontal.cards>.card>.image{border-radius:.28571429rem 0 0 .28571429rem;width:150px}.ui.card.horizontal>.image>img,.ui.horizontal.cards>.card>.image>img{background-size:cover;background-repeat:no-repeat;background-position:center;justify-content:center;align-items:center;display:flex;width:100%;border-radius:.28571429rem 0 0 .28571429rem}.ui.card.horizontal>.image:last-child>img,.ui.horizontal.cards>.card>.image:last-child>img{border-radius:0 .28571429rem .28571429rem 0}.ui.horizontal.card>.content,.ui.horizontal.cards>.card>.content{border-top:none;flex-basis:1px}.ui.horizontal.card>.extra,.ui.horizontal.cards>.card>.extra{flex-basis:100%}.ui.cards>.raised.card,.ui.raised.card,.ui.raised.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.link.cards .raised.card:hover,.ui.link.raised.card:hover,.ui.raised.cards a.card:hover,a.ui.raised.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 4px 0 rgba(34,36,38,.15),0 2px 10px 0 rgba(34,36,38,.25)}.ui.basic.cards>.raised.card,.ui.basic.raised.card,.ui.basic.raised.cards>.card,.ui.raised.cards>.basic.card{box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)}.ui.basic.raised.cards a.card:hover,.ui.link.basic.cards .raised.card:hover,.ui.link.basic.raised.card:hover,.ui.link.basic.raised.cards .card:hover,.ui.link.cards .basic.raised.card:hover,a.ui.basic.raised.card:hover{box-shadow:0 2px 4px 0 rgba(34,36,38,.15),0 2px 10px 0 rgba(34,36,38,.25)}.ui.centered.cards{justify-content:center}.ui.centered.card{margin-left:auto;margin-right:auto}.ui.fluid.card{width:100%;max-width:9999px}.ui.cards a.card,.ui.link.card,.ui.link.cards .card,a.ui.card{transform:none}.ui.cards a.card:hover,.ui.link.card:hover,.ui.link.cards .card:not(.icon):hover,a.ui.card:hover{cursor:pointer;z-index:5;background:#fff;border:none;box-shadow:0 1px 3px 0 #bcbdbd,0 0 0 1px #d4d4d5;transform:translateY(-3px)}.ui.cards>.primary.card,.ui.primary.card,.ui.primary.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #2185d0,0 1px 3px 0 #d4d4d5}.ui.cards a.primary.card:hover,.ui.link.cards .primary.card:not(.icon):hover,.ui.link.primary.card:hover,.ui.link.primary.cards .card:not(.icon):hover,.ui.primary.cards a.card:hover,a.ui.primary.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1678c2,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.primary.card,.ui.basic.primary.card,.ui.basic.primary.cards>.card,.ui.cards>.basic.primary.card{background:#54c8ff}.ui.basic.cards a.primary.card:hover,.ui.basic.primary.cards a.card:hover,.ui.cards a.basic.primary.card:hover,.ui.link.basic.cards .primary.card:not(.icon):hover,.ui.link.basic.primary.card:hover,.ui.link.basic.primary.cards .card:not(.icon):hover,.ui.link.cards .basic.primary.card:not(.icon):hover,a.ui.basic.primary.card:hover{background:#21b8ff}.ui.inverted.cards>.primary.card,.ui.inverted.primary.card,.ui.inverted.primary.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #54c8ff,0 0 0 1px #555}.ui.inverted.cards a.primary.card:hover,.ui.inverted.primary.cards a.card:hover,.ui.link.inverted.cards .primary.card:not(.icon):hover,.ui.link.inverted.primary.card:hover,.ui.link.inverted.primary.cards .card:not(.icon):hover,a.ui.inverted.primary.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #21b8ff,0 0 0 1px #555}.ui.basic.inverted.cards>.primary.card,.ui.basic.inverted.primary.card,.ui.basic.inverted.primary.cards>.card,.ui.inverted.cards>.basic.primary.card{background:#2185d0}.ui.basic.inverted.cards a.primary.card:hover,.ui.basic.inverted.primary.cards a.card:hover,.ui.inverted.cards a.basic.primary.card:hover,.ui.link.basic.inverted.cards .primary.card:not(.icon):hover,.ui.link.basic.inverted.primary.card:hover,.ui.link.basic.inverted.primary.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.primary.card:not(.icon):hover,a.ui.basic.inverted.primary.card:hover{background:#1678c2}.ui.cards>.secondary.card,.ui.secondary.card,.ui.secondary.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1b1c1d,0 1px 3px 0 #d4d4d5}.ui.cards a.secondary.card:hover,.ui.link.cards .secondary.card:not(.icon):hover,.ui.link.secondary.card:hover,.ui.link.secondary.cards .card:not(.icon):hover,.ui.secondary.cards a.card:hover,a.ui.secondary.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #27292a,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.secondary.card,.ui.basic.secondary.card,.ui.basic.secondary.cards>.card,.ui.cards>.basic.secondary.card{background:#545454}.ui.basic.cards a.secondary.card:hover,.ui.basic.secondary.cards a.card:hover,.ui.cards a.basic.secondary.card:hover,.ui.link.basic.cards .secondary.card:not(.icon):hover,.ui.link.basic.secondary.card:hover,.ui.link.basic.secondary.cards .card:not(.icon):hover,.ui.link.cards .basic.secondary.card:not(.icon):hover,a.ui.basic.secondary.card:hover{background:#6e6e6e}.ui.inverted.cards>.secondary.card,.ui.inverted.secondary.card,.ui.inverted.secondary.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #545454,0 0 0 1px #555}.ui.inverted.cards a.secondary.card:hover,.ui.inverted.secondary.cards a.card:hover,.ui.link.inverted.cards .secondary.card:not(.icon):hover,.ui.link.inverted.secondary.card:hover,.ui.link.inverted.secondary.cards .card:not(.icon):hover,a.ui.inverted.secondary.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #6e6e6e,0 0 0 1px #555}.ui.basic.inverted.cards>.secondary.card,.ui.basic.inverted.secondary.card,.ui.basic.inverted.secondary.cards>.card,.ui.inverted.cards>.basic.secondary.card{background:#1b1c1d}.ui.basic.inverted.cards a.secondary.card:hover,.ui.basic.inverted.secondary.cards a.card:hover,.ui.inverted.cards a.basic.secondary.card:hover,.ui.link.basic.inverted.cards .secondary.card:not(.icon):hover,.ui.link.basic.inverted.secondary.card:hover,.ui.link.basic.inverted.secondary.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.secondary.card:not(.icon):hover,a.ui.basic.inverted.secondary.card:hover{background:#27292a}.ui.cards>.red.card,.ui.red.card,.ui.red.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #db2828,0 1px 3px 0 #d4d4d5}.ui.cards a.red.card:hover,.ui.link.cards .red.card:not(.icon):hover,.ui.link.red.card:hover,.ui.link.red.cards .card:not(.icon):hover,.ui.red.cards a.card:hover,a.ui.red.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #d01919,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.red.card,.ui.basic.red.card,.ui.basic.red.cards>.card,.ui.cards>.basic.red.card{background:#ff695e}.ui.basic.cards a.red.card:hover,.ui.basic.red.cards a.card:hover,.ui.cards a.basic.red.card:hover,.ui.link.basic.cards .red.card:not(.icon):hover,.ui.link.basic.red.card:hover,.ui.link.basic.red.cards .card:not(.icon):hover,.ui.link.cards .basic.red.card:not(.icon):hover,a.ui.basic.red.card:hover{background:#ff392b}.ui.inverted.cards>.red.card,.ui.inverted.red.card,.ui.inverted.red.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #ff695e,0 0 0 1px #555}.ui.inverted.cards a.red.card:hover,.ui.inverted.red.cards a.card:hover,.ui.link.inverted.cards .red.card:not(.icon):hover,.ui.link.inverted.red.card:hover,.ui.link.inverted.red.cards .card:not(.icon):hover,a.ui.inverted.red.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #ff392b,0 0 0 1px #555}.ui.basic.inverted.cards>.red.card,.ui.basic.inverted.red.card,.ui.basic.inverted.red.cards>.card,.ui.inverted.cards>.basic.red.card{background:#db2828}.ui.basic.inverted.cards a.red.card:hover,.ui.basic.inverted.red.cards a.card:hover,.ui.inverted.cards a.basic.red.card:hover,.ui.link.basic.inverted.cards .red.card:not(.icon):hover,.ui.link.basic.inverted.red.card:hover,.ui.link.basic.inverted.red.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.red.card:not(.icon):hover,a.ui.basic.inverted.red.card:hover{background:#d01919}.ui.cards>.orange.card,.ui.orange.card,.ui.orange.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f2711c,0 1px 3px 0 #d4d4d5}.ui.cards a.orange.card:hover,.ui.link.cards .orange.card:not(.icon):hover,.ui.link.orange.card:hover,.ui.link.orange.cards .card:not(.icon):hover,.ui.orange.cards a.card:hover,a.ui.orange.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #f26202,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.orange.card,.ui.basic.orange.card,.ui.basic.orange.cards>.card,.ui.cards>.basic.orange.card{background:#ff851b}.ui.basic.cards a.orange.card:hover,.ui.basic.orange.cards a.card:hover,.ui.cards a.basic.orange.card:hover,.ui.link.basic.cards .orange.card:not(.icon):hover,.ui.link.basic.orange.card:hover,.ui.link.basic.orange.cards .card:not(.icon):hover,.ui.link.cards .basic.orange.card:not(.icon):hover,a.ui.basic.orange.card:hover{background:#e76b00}.ui.inverted.cards>.orange.card,.ui.inverted.orange.card,.ui.inverted.orange.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #ff851b,0 0 0 1px #555}.ui.inverted.cards a.orange.card:hover,.ui.inverted.orange.cards a.card:hover,.ui.link.inverted.cards .orange.card:not(.icon):hover,.ui.link.inverted.orange.card:hover,.ui.link.inverted.orange.cards .card:not(.icon):hover,a.ui.inverted.orange.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #e76b00,0 0 0 1px #555}.ui.basic.inverted.cards>.orange.card,.ui.basic.inverted.orange.card,.ui.basic.inverted.orange.cards>.card,.ui.inverted.cards>.basic.orange.card{background:#f2711c}.ui.basic.inverted.cards a.orange.card:hover,.ui.basic.inverted.orange.cards a.card:hover,.ui.inverted.cards a.basic.orange.card:hover,.ui.link.basic.inverted.cards .orange.card:not(.icon):hover,.ui.link.basic.inverted.orange.card:hover,.ui.link.basic.inverted.orange.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.orange.card:not(.icon):hover,a.ui.basic.inverted.orange.card:hover{background:#f26202}.ui.cards>.yellow.card,.ui.yellow.card,.ui.yellow.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #fbbd08,0 1px 3px 0 #d4d4d5}.ui.cards a.yellow.card:hover,.ui.link.cards .yellow.card:not(.icon):hover,.ui.link.yellow.card:hover,.ui.link.yellow.cards .card:not(.icon):hover,.ui.yellow.cards a.card:hover,a.ui.yellow.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #eaae00,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.yellow.card,.ui.basic.yellow.card,.ui.basic.yellow.cards>.card,.ui.cards>.basic.yellow.card{background:#ffe21f}.ui.basic.cards a.yellow.card:hover,.ui.basic.yellow.cards a.card:hover,.ui.cards a.basic.yellow.card:hover,.ui.link.basic.cards .yellow.card:not(.icon):hover,.ui.link.basic.yellow.card:hover,.ui.link.basic.yellow.cards .card:not(.icon):hover,.ui.link.cards .basic.yellow.card:not(.icon):hover,a.ui.basic.yellow.card:hover{background:#ebcd00}.ui.inverted.cards>.yellow.card,.ui.inverted.yellow.card,.ui.inverted.yellow.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #ffe21f,0 0 0 1px #555}.ui.inverted.cards a.yellow.card:hover,.ui.inverted.yellow.cards a.card:hover,.ui.link.inverted.cards .yellow.card:not(.icon):hover,.ui.link.inverted.yellow.card:hover,.ui.link.inverted.yellow.cards .card:not(.icon):hover,a.ui.inverted.yellow.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #ebcd00,0 0 0 1px #555}.ui.basic.inverted.cards>.yellow.card,.ui.basic.inverted.yellow.card,.ui.basic.inverted.yellow.cards>.card,.ui.inverted.cards>.basic.yellow.card{background:#fbbd08}.ui.basic.inverted.cards a.yellow.card:hover,.ui.basic.inverted.yellow.cards a.card:hover,.ui.inverted.cards a.basic.yellow.card:hover,.ui.link.basic.inverted.cards .yellow.card:not(.icon):hover,.ui.link.basic.inverted.yellow.card:hover,.ui.link.basic.inverted.yellow.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.yellow.card:not(.icon):hover,a.ui.basic.inverted.yellow.card:hover{background:#eaae00}.ui.cards>.olive.card,.ui.olive.card,.ui.olive.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #b5cc18,0 1px 3px 0 #d4d4d5}.ui.cards a.olive.card:hover,.ui.link.cards .olive.card:not(.icon):hover,.ui.link.olive.card:hover,.ui.link.olive.cards .card:not(.icon):hover,.ui.olive.cards a.card:hover,a.ui.olive.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a7bd0d,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.olive.card,.ui.basic.olive.card,.ui.basic.olive.cards>.card,.ui.cards>.basic.olive.card{background:#d9e778}.ui.basic.cards a.olive.card:hover,.ui.basic.olive.cards a.card:hover,.ui.cards a.basic.olive.card:hover,.ui.link.basic.cards .olive.card:not(.icon):hover,.ui.link.basic.olive.card:hover,.ui.link.basic.olive.cards .card:not(.icon):hover,.ui.link.cards .basic.olive.card:not(.icon):hover,a.ui.basic.olive.card:hover{background:#d2e745}.ui.inverted.cards>.olive.card,.ui.inverted.olive.card,.ui.inverted.olive.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #d9e778,0 0 0 1px #555}.ui.inverted.cards a.olive.card:hover,.ui.inverted.olive.cards a.card:hover,.ui.link.inverted.cards .olive.card:not(.icon):hover,.ui.link.inverted.olive.card:hover,.ui.link.inverted.olive.cards .card:not(.icon):hover,a.ui.inverted.olive.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #d2e745,0 0 0 1px #555}.ui.basic.inverted.cards>.olive.card,.ui.basic.inverted.olive.card,.ui.basic.inverted.olive.cards>.card,.ui.inverted.cards>.basic.olive.card{background:#b5cc18}.ui.basic.inverted.cards a.olive.card:hover,.ui.basic.inverted.olive.cards a.card:hover,.ui.inverted.cards a.basic.olive.card:hover,.ui.link.basic.inverted.cards .olive.card:not(.icon):hover,.ui.link.basic.inverted.olive.card:hover,.ui.link.basic.inverted.olive.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.olive.card:not(.icon):hover,a.ui.basic.inverted.olive.card:hover{background:#a7bd0d}.ui.cards>.green.card,.ui.green.card,.ui.green.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #21ba45,0 1px 3px 0 #d4d4d5}.ui.cards a.green.card:hover,.ui.green.cards a.card:hover,.ui.link.cards .green.card:not(.icon):hover,.ui.link.green.card:hover,.ui.link.green.cards .card:not(.icon):hover,a.ui.green.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #16ab39,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.green.card,.ui.basic.green.card,.ui.basic.green.cards>.card,.ui.cards>.basic.green.card{background:#2ecc40}.ui.basic.cards a.green.card:hover,.ui.basic.green.cards a.card:hover,.ui.cards a.basic.green.card:hover,.ui.link.basic.cards .green.card:not(.icon):hover,.ui.link.basic.green.card:hover,.ui.link.basic.green.cards .card:not(.icon):hover,.ui.link.cards .basic.green.card:not(.icon):hover,a.ui.basic.green.card:hover{background:#1ea92e}.ui.inverted.cards>.green.card,.ui.inverted.green.card,.ui.inverted.green.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #2ecc40,0 0 0 1px #555}.ui.inverted.cards a.green.card:hover,.ui.inverted.green.cards a.card:hover,.ui.link.inverted.cards .green.card:not(.icon):hover,.ui.link.inverted.green.card:hover,.ui.link.inverted.green.cards .card:not(.icon):hover,a.ui.inverted.green.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #1ea92e,0 0 0 1px #555}.ui.basic.inverted.cards>.green.card,.ui.basic.inverted.green.card,.ui.basic.inverted.green.cards>.card,.ui.inverted.cards>.basic.green.card{background:#21ba45}.ui.basic.inverted.cards a.green.card:hover,.ui.basic.inverted.green.cards a.card:hover,.ui.inverted.cards a.basic.green.card:hover,.ui.link.basic.inverted.cards .green.card:not(.icon):hover,.ui.link.basic.inverted.green.card:hover,.ui.link.basic.inverted.green.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.green.card:not(.icon):hover,a.ui.basic.inverted.green.card:hover{background:#16ab39}.ui.cards>.teal.card,.ui.teal.card,.ui.teal.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #00b5ad,0 1px 3px 0 #d4d4d5}.ui.cards a.teal.card:hover,.ui.link.cards .teal.card:not(.icon):hover,.ui.link.teal.card:hover,.ui.link.teal.cards .card:not(.icon):hover,.ui.teal.cards a.card:hover,a.ui.teal.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #009c95,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.teal.card,.ui.basic.teal.card,.ui.basic.teal.cards>.card,.ui.cards>.basic.teal.card{background:#6dffff}.ui.basic.cards a.teal.card:hover,.ui.basic.teal.cards a.card:hover,.ui.cards a.basic.teal.card:hover,.ui.link.basic.cards .teal.card:not(.icon):hover,.ui.link.basic.teal.card:hover,.ui.link.basic.teal.cards .card:not(.icon):hover,.ui.link.cards .basic.teal.card:not(.icon):hover,a.ui.basic.teal.card:hover{background:#3affff}.ui.inverted.cards>.teal.card,.ui.inverted.teal.card,.ui.inverted.teal.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #6dffff,0 0 0 1px #555}.ui.inverted.cards a.teal.card:hover,.ui.inverted.teal.cards a.card:hover,.ui.link.inverted.cards .teal.card:not(.icon):hover,.ui.link.inverted.teal.card:hover,.ui.link.inverted.teal.cards .card:not(.icon):hover,a.ui.inverted.teal.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #3affff,0 0 0 1px #555}.ui.basic.inverted.cards>.teal.card,.ui.basic.inverted.teal.card,.ui.basic.inverted.teal.cards>.card,.ui.inverted.cards>.basic.teal.card{background:#00b5ad}.ui.basic.inverted.cards a.teal.card:hover,.ui.basic.inverted.teal.cards a.card:hover,.ui.inverted.cards a.basic.teal.card:hover,.ui.link.basic.inverted.cards .teal.card:not(.icon):hover,.ui.link.basic.inverted.teal.card:hover,.ui.link.basic.inverted.teal.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.teal.card:not(.icon):hover,a.ui.basic.inverted.teal.card:hover{background:#009c95}.ui.blue.card,.ui.blue.cards>.card,.ui.cards>.blue.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #2185d0,0 1px 3px 0 #d4d4d5}.ui.blue.cards a.card:hover,.ui.cards a.blue.card:hover,.ui.link.blue.card:hover,.ui.link.blue.cards .card:not(.icon):hover,.ui.link.cards .blue.card:not(.icon):hover,a.ui.blue.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1678c2,0 1px 3px 0 #bcbdbd}.ui.basic.blue.card,.ui.basic.blue.cards>.card,.ui.basic.cards>.blue.card,.ui.cards>.basic.blue.card{background:#54c8ff}.ui.basic.blue.cards a.card:hover,.ui.basic.cards a.blue.card:hover,.ui.cards a.basic.blue.card:hover,.ui.link.basic.blue.card:hover,.ui.link.basic.blue.cards .card:not(.icon):hover,.ui.link.basic.cards .blue.card:not(.icon):hover,.ui.link.cards .basic.blue.card:not(.icon):hover,a.ui.basic.blue.card:hover{background:#21b8ff}.ui.inverted.blue.card,.ui.inverted.blue.cards>.card,.ui.inverted.cards>.blue.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #54c8ff,0 0 0 1px #555}.ui.inverted.blue.cards a.card:hover,.ui.inverted.cards a.blue.card:hover,.ui.link.inverted.blue.card:hover,.ui.link.inverted.blue.cards .card:not(.icon):hover,.ui.link.inverted.cards .blue.card:not(.icon):hover,a.ui.inverted.blue.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #21b8ff,0 0 0 1px #555}.ui.basic.inverted.blue.card,.ui.basic.inverted.blue.cards>.card,.ui.basic.inverted.cards>.blue.card,.ui.inverted.cards>.basic.blue.card{background:#2185d0}.ui.basic.inverted.blue.cards a.card:hover,.ui.basic.inverted.cards a.blue.card:hover,.ui.inverted.cards a.basic.blue.card:hover,.ui.link.basic.inverted.blue.card:hover,.ui.link.basic.inverted.blue.cards .card:not(.icon):hover,.ui.link.basic.inverted.cards .blue.card:not(.icon):hover,.ui.link.inverted.cards .basic.blue.card:not(.icon):hover,a.ui.basic.inverted.blue.card:hover{background:#1678c2}.ui.cards>.violet.card,.ui.violet.card,.ui.violet.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #6435c9,0 1px 3px 0 #d4d4d5}.ui.cards a.violet.card:hover,.ui.link.cards .violet.card:not(.icon):hover,.ui.link.violet.card:hover,.ui.link.violet.cards .card:not(.icon):hover,.ui.violet.cards a.card:hover,a.ui.violet.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #5829bb,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.violet.card,.ui.basic.violet.card,.ui.basic.violet.cards>.card,.ui.cards>.basic.violet.card{background:#a291fb}.ui.basic.cards a.violet.card:hover,.ui.basic.violet.cards a.card:hover,.ui.cards a.basic.violet.card:hover,.ui.link.basic.cards .violet.card:not(.icon):hover,.ui.link.basic.violet.card:hover,.ui.link.basic.violet.cards .card:not(.icon):hover,.ui.link.cards .basic.violet.card:not(.icon):hover,a.ui.basic.violet.card:hover{background:#745aff}.ui.inverted.cards>.violet.card,.ui.inverted.violet.card,.ui.inverted.violet.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #a291fb,0 0 0 1px #555}.ui.inverted.cards a.violet.card:hover,.ui.inverted.violet.cards a.card:hover,.ui.link.inverted.cards .violet.card:not(.icon):hover,.ui.link.inverted.violet.card:hover,.ui.link.inverted.violet.cards .card:not(.icon):hover,a.ui.inverted.violet.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #745aff,0 0 0 1px #555}.ui.basic.inverted.cards>.violet.card,.ui.basic.inverted.violet.card,.ui.basic.inverted.violet.cards>.card,.ui.inverted.cards>.basic.violet.card{background:#6435c9}.ui.basic.inverted.cards a.violet.card:hover,.ui.basic.inverted.violet.cards a.card:hover,.ui.inverted.cards a.basic.violet.card:hover,.ui.link.basic.inverted.cards .violet.card:not(.icon):hover,.ui.link.basic.inverted.violet.card:hover,.ui.link.basic.inverted.violet.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.violet.card:not(.icon):hover,a.ui.basic.inverted.violet.card:hover{background:#5829bb}.ui.cards>.purple.card,.ui.purple.card,.ui.purple.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a333c8,0 1px 3px 0 #d4d4d5}.ui.cards a.purple.card:hover,.ui.link.cards .purple.card:not(.icon):hover,.ui.link.purple.card:hover,.ui.link.purple.cards .card:not(.icon):hover,.ui.purple.cards a.card:hover,a.ui.purple.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #9627ba,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.purple.card,.ui.basic.purple.card,.ui.basic.purple.cards>.card,.ui.cards>.basic.purple.card{background:#dc73ff}.ui.basic.cards a.purple.card:hover,.ui.basic.purple.cards a.card:hover,.ui.cards a.basic.purple.card:hover,.ui.link.basic.cards .purple.card:not(.icon):hover,.ui.link.basic.purple.card:hover,.ui.link.basic.purple.cards .card:not(.icon):hover,.ui.link.cards .basic.purple.card:not(.icon):hover,a.ui.basic.purple.card:hover{background:#cf40ff}.ui.inverted.cards>.purple.card,.ui.inverted.purple.card,.ui.inverted.purple.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #dc73ff,0 0 0 1px #555}.ui.inverted.cards a.purple.card:hover,.ui.inverted.purple.cards a.card:hover,.ui.link.inverted.cards .purple.card:not(.icon):hover,.ui.link.inverted.purple.card:hover,.ui.link.inverted.purple.cards .card:not(.icon):hover,a.ui.inverted.purple.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #cf40ff,0 0 0 1px #555}.ui.basic.inverted.cards>.purple.card,.ui.basic.inverted.purple.card,.ui.basic.inverted.purple.cards>.card,.ui.inverted.cards>.basic.purple.card{background:#a333c8}.ui.basic.inverted.cards a.purple.card:hover,.ui.basic.inverted.purple.cards a.card:hover,.ui.inverted.cards a.basic.purple.card:hover,.ui.link.basic.inverted.cards .purple.card:not(.icon):hover,.ui.link.basic.inverted.purple.card:hover,.ui.link.basic.inverted.purple.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.purple.card:not(.icon):hover,a.ui.basic.inverted.purple.card:hover{background:#9627ba}.ui.cards>.pink.card,.ui.pink.card,.ui.pink.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e03997,0 1px 3px 0 #d4d4d5}.ui.cards a.pink.card:hover,.ui.link.cards .pink.card:not(.icon):hover,.ui.link.pink.card:hover,.ui.link.pink.cards .card:not(.icon):hover,.ui.pink.cards a.card:hover,a.ui.pink.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #e61a8d,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.pink.card,.ui.basic.pink.card,.ui.basic.pink.cards>.card,.ui.cards>.basic.pink.card{background:#ff8edf}.ui.basic.cards a.pink.card:hover,.ui.basic.pink.cards a.card:hover,.ui.cards a.basic.pink.card:hover,.ui.link.basic.cards .pink.card:not(.icon):hover,.ui.link.basic.pink.card:hover,.ui.link.basic.pink.cards .card:not(.icon):hover,.ui.link.cards .basic.pink.card:not(.icon):hover,a.ui.basic.pink.card:hover{background:#ff5bd1}.ui.inverted.cards>.pink.card,.ui.inverted.pink.card,.ui.inverted.pink.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #ff8edf,0 0 0 1px #555}.ui.inverted.cards a.pink.card:hover,.ui.inverted.pink.cards a.card:hover,.ui.link.inverted.cards .pink.card:not(.icon):hover,.ui.link.inverted.pink.card:hover,.ui.link.inverted.pink.cards .card:not(.icon):hover,a.ui.inverted.pink.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #ff5bd1,0 0 0 1px #555}.ui.basic.inverted.cards>.pink.card,.ui.basic.inverted.pink.card,.ui.basic.inverted.pink.cards>.card,.ui.inverted.cards>.basic.pink.card{background:#e03997}.ui.basic.inverted.cards a.pink.card:hover,.ui.basic.inverted.pink.cards a.card:hover,.ui.inverted.cards a.basic.pink.card:hover,.ui.link.basic.inverted.cards .pink.card:not(.icon):hover,.ui.link.basic.inverted.pink.card:hover,.ui.link.basic.inverted.pink.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.pink.card:not(.icon):hover,a.ui.basic.inverted.pink.card:hover{background:#e61a8d}.ui.brown.card,.ui.brown.cards>.card,.ui.cards>.brown.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #a5673f,0 1px 3px 0 #d4d4d5}.ui.brown.cards a.card:hover,.ui.cards a.brown.card:hover,.ui.link.brown.card:hover,.ui.link.brown.cards .card:not(.icon):hover,.ui.link.cards .brown.card:not(.icon):hover,a.ui.brown.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #975b33,0 1px 3px 0 #bcbdbd}.ui.basic.brown.card,.ui.basic.brown.cards>.card,.ui.basic.cards>.brown.card,.ui.cards>.basic.brown.card{background:#d67c1c}.ui.basic.brown.cards a.card:hover,.ui.basic.cards a.brown.card:hover,.ui.cards a.basic.brown.card:hover,.ui.link.basic.brown.card:hover,.ui.link.basic.brown.cards .card:not(.icon):hover,.ui.link.basic.cards .brown.card:not(.icon):hover,.ui.link.cards .basic.brown.card:not(.icon):hover,a.ui.basic.brown.card:hover{background:#b0620f}.ui.inverted.brown.card,.ui.inverted.brown.cards>.card,.ui.inverted.cards>.brown.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #d67c1c,0 0 0 1px #555}.ui.inverted.brown.cards a.card:hover,.ui.inverted.cards a.brown.card:hover,.ui.link.inverted.brown.card:hover,.ui.link.inverted.brown.cards .card:not(.icon):hover,.ui.link.inverted.cards .brown.card:not(.icon):hover,a.ui.inverted.brown.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #b0620f,0 0 0 1px #555}.ui.basic.inverted.brown.card,.ui.basic.inverted.brown.cards>.card,.ui.basic.inverted.cards>.brown.card,.ui.inverted.cards>.basic.brown.card{background:#a5673f}.ui.basic.inverted.brown.cards a.card:hover,.ui.basic.inverted.cards a.brown.card:hover,.ui.inverted.cards a.basic.brown.card:hover,.ui.link.basic.inverted.brown.card:hover,.ui.link.basic.inverted.brown.cards .card:not(.icon):hover,.ui.link.basic.inverted.cards .brown.card:not(.icon):hover,.ui.link.inverted.cards .basic.brown.card:not(.icon):hover,a.ui.basic.inverted.brown.card:hover{background:#975b33}.ui.cards>.grey.card,.ui.grey.card,.ui.grey.cards>.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #767676,0 1px 3px 0 #d4d4d5}.ui.cards a.grey.card:hover,.ui.grey.cards a.card:hover,.ui.link.cards .grey.card:not(.icon):hover,.ui.link.grey.card:hover,.ui.link.grey.cards .card:not(.icon):hover,a.ui.grey.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #838383,0 1px 3px 0 #bcbdbd}.ui.basic.cards>.grey.card,.ui.basic.grey.card,.ui.basic.grey.cards>.card,.ui.cards>.basic.grey.card{background:#dcddde}.ui.basic.cards a.grey.card:hover,.ui.basic.grey.cards a.card:hover,.ui.cards a.basic.grey.card:hover,.ui.link.basic.cards .grey.card:not(.icon):hover,.ui.link.basic.grey.card:hover,.ui.link.basic.grey.cards .card:not(.icon):hover,.ui.link.cards .basic.grey.card:not(.icon):hover,a.ui.basic.grey.card:hover{background:#c2c4c5}.ui.inverted.cards>.grey.card,.ui.inverted.grey.card,.ui.inverted.grey.cards>.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #dcddde,0 0 0 1px #555}.ui.inverted.cards a.grey.card:hover,.ui.inverted.grey.cards a.card:hover,.ui.link.inverted.cards .grey.card:not(.icon):hover,.ui.link.inverted.grey.card:hover,.ui.link.inverted.grey.cards .card:not(.icon):hover,a.ui.inverted.grey.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #c2c4c5,0 0 0 1px #555}.ui.basic.inverted.cards>.grey.card,.ui.basic.inverted.grey.card,.ui.basic.inverted.grey.cards>.card,.ui.inverted.cards>.basic.grey.card{background:#767676}.ui.basic.inverted.cards a.grey.card:hover,.ui.basic.inverted.grey.cards a.card:hover,.ui.inverted.cards a.basic.grey.card:hover,.ui.link.basic.inverted.cards .grey.card:not(.icon):hover,.ui.link.basic.inverted.grey.card:hover,.ui.link.basic.inverted.grey.cards .card:not(.icon):hover,.ui.link.inverted.cards .basic.grey.card:not(.icon):hover,a.ui.basic.inverted.grey.card:hover{background:#838383}.ui.black.card,.ui.black.cards>.card,.ui.cards>.black.card{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #1b1c1d,0 1px 3px 0 #d4d4d5}.ui.black.cards a.card:hover,.ui.cards a.black.card:hover,.ui.link.black.card:hover,.ui.link.black.cards .card:not(.icon):hover,.ui.link.cards .black.card:not(.icon):hover,a.ui.black.card:hover{box-shadow:0 0 0 1px #d4d4d5,0 2px 0 0 #27292a,0 1px 3px 0 #bcbdbd}.ui.basic.black.card,.ui.basic.black.cards>.card,.ui.basic.cards>.black.card,.ui.cards>.basic.black.card{background:#545454}.ui.basic.black.card .content,.ui.basic.black.card .description,.ui.basic.black.card .header,.ui.basic.black.card .meta,.ui.basic.black.cards>.card .content,.ui.basic.black.cards>.card .description,.ui.basic.black.cards>.card .header,.ui.basic.black.cards>.card .meta,.ui.basic.cards>.black.card .content,.ui.basic.cards>.black.card .description,.ui.basic.cards>.black.card .header,.ui.basic.cards>.black.card .meta,.ui.cards>.basic.black.card .content,.ui.cards>.basic.black.card .description,.ui.cards>.basic.black.card .header,.ui.cards>.basic.black.card .meta{color:#fff}.ui.basic.black.cards a.card:hover,.ui.basic.cards a.black.card:hover,.ui.cards a.basic.black.card:hover,.ui.link.basic.black.card:hover,.ui.link.basic.black.cards .card:not(.icon):hover,.ui.link.basic.cards .black.card:not(.icon):hover,.ui.link.cards .basic.black.card:not(.icon):hover,a.ui.basic.black.card:hover{background:#000}.ui.inverted.black.card,.ui.inverted.black.cards>.card,.ui.inverted.cards>.black.card{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #545454,0 0 0 1px #555}.ui.inverted.black.cards a.card:hover,.ui.inverted.cards a.black.card:hover,.ui.link.inverted.black.card:hover,.ui.link.inverted.black.cards .card:not(.icon):hover,.ui.link.inverted.cards .black.card:not(.icon):hover,a.ui.inverted.black.card:hover{box-shadow:0 1px 3px 0 #555,0 2px 0 0 #000,0 0 0 1px #555}.ui.basic.inverted.black.card,.ui.basic.inverted.black.cards>.card,.ui.basic.inverted.cards>.black.card,.ui.inverted.cards>.basic.black.card{background:#1b1c1d}.ui.basic.inverted.black.cards a.card:hover,.ui.basic.inverted.cards a.black.card:hover,.ui.inverted.cards a.basic.black.card:hover,.ui.link.basic.inverted.black.card:hover,.ui.link.basic.inverted.black.cards .card:not(.icon):hover,.ui.link.basic.inverted.cards .black.card:not(.icon):hover,.ui.link.inverted.cards .basic.black.card:not(.icon):hover,a.ui.basic.inverted.black.card:hover{background:#27292a}.ui.one.cards{margin-left:0;margin-right:0}.ui.one.cards>.card{width:100%}.ui.two.cards{margin-left:-1em;margin-right:-1em}.ui.two.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.three.cards{margin-left:-1em;margin-right:-1em}.ui.three.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}.ui.four.cards{margin-left:-.75em;margin-right:-.75em}.ui.four.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.five.cards{margin-left:-.75em;margin-right:-.75em}.ui.five.cards>.card{width:calc(20% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.six.cards{margin-left:-.75em;margin-right:-.75em}.ui.six.cards>.card{width:calc(16.666666666666664% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.seven.cards{margin-left:-.5em;margin-right:-.5em}.ui.seven.cards>.card{width:calc(14.285714285714285% - 1em);margin-left:.5em;margin-right:.5em}.ui.eight.cards{margin-left:-.5em;margin-right:-.5em}.ui.eight.cards>.card{width:calc(12.5% - 1em);margin-left:.5em;margin-right:.5em;font-size:11px}.ui.nine.cards{margin-left:-.5em;margin-right:-.5em}.ui.nine.cards>.card{width:calc(11.11111111111111% - 1em);margin-left:.5em;margin-right:.5em;font-size:10px}.ui.ten.cards{margin-left:-.5em;margin-right:-.5em}.ui.ten.cards>.card{width:calc(10% - 1em);margin-left:.5em;margin-right:.5em}@media only screen and (max-width:767.98px){.ui.two.doubling.cards{margin-left:0;margin-right:0}.ui.two.doubling.cards>.card{width:100%;margin-left:0;margin-right:0}.ui.three.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.three.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.four.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.four.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.five.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.five.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.six.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.six.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.seven.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.seven.doubling.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.eight.doubling.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}.ui.nine.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.nine.doubling.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}.ui.ten.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.ten.doubling.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.two.doubling.cards{margin-left:0;margin-right:0}.ui.two.doubling.cards>.card{width:100%;margin-left:0;margin-right:0}.ui.three.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.three.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.four.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.four.doubling.cards>.card{width:calc(50% - 2em);margin-left:1em;margin-right:1em}.ui.five.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.five.doubling.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}.ui.six.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.six.doubling.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-1em;margin-right:-1em}.ui.eight.doubling.cards>.card{width:calc(33.33333333333333% - 2em);margin-left:1em;margin-right:1em}.ui.eight.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.eight.doubling.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.nine.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.nine.doubling.cards>.card{width:calc(25% - 1.5em);margin-left:.75em;margin-right:.75em}.ui.ten.doubling.cards{margin-left:-.75em;margin-right:-.75em}.ui.ten.doubling.cards>.card{width:calc(20% - 1.5em);margin-left:.75em;margin-right:.75em}}@media only screen and (max-width:767.98px){.ui.stackable.cards{display:block!important}.ui.stackable.cards .card:first-child{margin-top:0!important}.ui.stackable.cards>.card{display:block!important;height:auto!important;margin:1em 1em;padding:0!important;width:calc(100% - 2em)!important}}.ui.cards>.card{font-size:1em}.ui.mini.card,.ui.mini.cards .card{font-size:.78571429rem}.ui.tiny.card,.ui.tiny.cards .card{font-size:.85714286rem}.ui.small.card,.ui.small.cards .card{font-size:.92857143rem}.ui.large.card,.ui.large.cards .card{font-size:1.14285714rem}.ui.big.card,.ui.big.cards .card{font-size:1.28571429rem}.ui.huge.card,.ui.huge.cards .card{font-size:1.42857143rem}.ui.massive.card,.ui.massive.cards .card{font-size:1.71428571rem}.ui.inverted.card,.ui.inverted.cards>.card{background:#1b1c1d;box-shadow:0 1px 3px 0 #555,0 0 0 1px #555}.ui.inverted.card>.content,.ui.inverted.cards>.card>.content{border-top:1px solid rgba(255,255,255,.15)}.ui.inverted.card>.content>.header,.ui.inverted.cards>.card>.content>.header{color:rgba(255,255,255,.9)}.ui.inverted.card>.content>a.header,.ui.inverted.cards>.card>.content>a.header{color:rgba(255,255,255,.9)}.ui.inverted.card>.content>a.header:hover,.ui.inverted.cards>.card>.content>a.header:hover{color:#1e70bf}.ui.inverted.card>.content>.description,.ui.inverted.cards>.card>.content>.description{color:rgba(255,255,255,.8)}.ui.inverted.card .meta,.ui.inverted.cards>.card .meta{color:rgba(255,255,255,.7)}.ui.inverted.card .meta>a:not(.ui),.ui.inverted.cards>.card .meta>a:not(.ui){color:rgba(255,255,255,.7)}.ui.inverted.card .meta>a:not(.ui):hover,.ui.inverted.cards>.card .meta>a:not(.ui):hover{color:#fff}.ui.inverted.card>.extra,.ui.inverted.cards>.card>.extra{border-top:1px solid rgba(255,255,255,.15)!important;color:rgba(255,255,255,.7)}.ui.inverted.card>.extra a:not(.ui),.ui.inverted.cards>.card>.extra a:not(.ui){color:rgba(255,255,255,.5)}.ui.inverted.card>.extra a:not(.ui):hover,.ui.inverted.cards>.card>.extra a:not(.ui):hover{color:#1e70bf}.ui.inverted.cards a.card:hover,.ui.inverted.link.card:hover,.ui.inverted.link.cards .card:not(.icon):hover,a.inverted.ui.card:hover{background:#1b1c1d}.ui.inverted.loading.card{color:#fff}.ui.inverted.loading.card::before{background:rgba(0,0,0,.85)} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.css b/internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.css new file mode 100755 index 0000000..a75ecb1 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.css @@ -0,0 +1,9 @@ +/*! + * # Fomantic-UI 2.9.3 - Checkbox + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */.ui.checkbox{position:relative;display:inline-block;-webkit-backface-visibility:hidden;backface-visibility:hidden;outline:0;vertical-align:baseline;font-style:normal;min-height:17px;font-size:1em;line-height:17px;min-width:17px}.ui.checkbox input[type=checkbox],.ui.checkbox input[type=radio]{cursor:pointer;position:absolute;top:0;left:0;opacity:0!important;outline:0;z-index:3;width:17px;height:17px}.ui.checkbox label{cursor:auto;position:relative;display:block;outline:0;font-size:1em}.ui.checkbox:not(.invisible) label{padding-left:1.85714em}.ui.checkbox label::before{position:absolute;top:0;left:0;width:17px;height:17px;content:"";background:#fff;border-radius:.21428571rem;transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease;border:1px solid #d4d4d5}.ui.checkbox label::after{position:absolute;font-size:14px;top:0;left:0;width:17px;height:17px;text-align:center;opacity:0;color:rgba(0,0,0,.87);transition:border .1s ease,opacity .1s ease,transform .1s ease,box-shadow .1s ease}.ui.right.aligned.checkbox label{padding-left:0;padding-right:1.85714em}.ui.right.aligned.checkbox label::after,.ui.right.aligned.checkbox label::before{right:0;left:auto}.ui.checkbox label,.ui.checkbox+label{color:rgba(0,0,0,.87);transition:color .1s ease}.ui.checkbox+label{vertical-align:middle}.ui.checkbox label:hover::before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox:not(.invisible) label:hover,.ui.checkbox:not(.invisible)+label:hover{color:rgba(0,0,0,.8)}.ui.checkbox label:active::before{background:#f9fafb;border-color:rgba(34,36,38,.35)}.ui.checkbox label:active::after{color:rgba(0,0,0,.95)}.ui.checkbox:not(.invisible) input:active~label{color:rgba(0,0,0,.95)}.ui.checkbox input:focus~label::before{background:#fff;border-color:#96c8da}.ui.checkbox input:focus~label::after{color:rgba(0,0,0,.95)}.ui.checkbox:not(.invisible) input:focus~label{color:rgba(0,0,0,.95)}.ui.checkbox input:checked~label::before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox input:checked~label::after{opacity:1;color:rgba(0,0,0,.95)}.ui.checkbox input:not([type=radio]):indeterminate~label::before{background:#fff;border-color:rgba(34,36,38,.35)}.ui.checkbox input:not([type=radio]):indeterminate~label::after{opacity:1;color:rgba(0,0,0,.95)}.ui.indeterminate.toggle.checkbox input:not([type=radio]):indeterminate~label::before{background:rgba(0,0,0,.15)}.ui.indeterminate.toggle.checkbox input:not([type=radio])~label::after{left:1.075rem}.ui.right.aligned.indeterminate.toggle.checkbox input:not([type=radio])~label::after{left:auto;right:1.075rem}.ui.checkbox input:checked:focus~label::before,.ui.checkbox input:not([type=radio]):indeterminate:focus~label::before{background:#fff;border-color:#96c8da}.ui.checkbox input:checked:focus~label::after,.ui.checkbox input:not([type=radio]):indeterminate:focus~label::after{color:rgba(0,0,0,.95)}.ui.read-only.checkbox,.ui.read-only.checkbox label{cursor:default;pointer-events:none}.ui.checkbox input[disabled]~label,.ui.disabled.checkbox label{cursor:default;opacity:.5;color:#000;pointer-events:none}.ui.checkbox input.hidden{z-index:-1}.ui.checkbox input+label[for],.ui.checkbox input.hidden+label{cursor:pointer;-webkit-user-select:none;-ms-user-select:none;user-select:none}.ui.radio.checkbox{min-height:15px}.ui.radio.checkbox label{padding-left:1.85714em}.ui.radio.checkbox label::before{content:"";transform:none;width:15px;height:15px;border-radius:500rem;top:1px;left:0}.ui.radio.checkbox label::after{border:none;content:""!important;line-height:15px;top:1px;left:0;width:15px;height:15px;border-radius:500rem;transform:scale(.46666667);background-color:rgba(0,0,0,.87)}.ui.radio.checkbox input:focus~label::before{background-color:#fff}.ui.radio.checkbox input:focus~label::after{background-color:rgba(0,0,0,.95)}.ui.radio.checkbox input:indeterminate~label::after{opacity:0}.ui.radio.checkbox input:checked~label::before{background-color:#fff}.ui.radio.checkbox input:checked~label::after{background-color:rgba(0,0,0,.95)}.ui.radio.checkbox input:focus:checked~label::before{background-color:#fff}.ui.radio.checkbox input:focus:checked~label::after{background-color:rgba(0,0,0,.95)}.ui.slider.checkbox{min-height:1.25rem}.ui.slider.checkbox input{width:3.5rem;height:1.25rem}.ui.slider.checkbox label{padding-left:4.5rem;line-height:1rem;color:rgba(0,0,0,.4)}.ui.slider.checkbox label::before{display:block;position:absolute;content:"";transform:none;border:none!important;left:0;z-index:1;top:.4rem;background-color:rgba(0,0,0,.05);width:3.5rem;height:.21428571rem;border-radius:500rem;transition:background .3s ease}.ui.slider.checkbox label::after{background:#fff linear-gradient(transparent,rgba(0,0,0,.05));position:absolute;content:""!important;opacity:1;z-index:2;border:none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;width:1.5rem;height:1.5rem;top:-.25rem;left:0;transform:none;border-radius:500rem;transition:left .3s ease}.ui.slider.checkbox input:focus~label::before{background-color:rgba(0,0,0,.15);border:none}.ui.slider.checkbox label:hover{color:rgba(0,0,0,.8)}.ui.slider.checkbox label:hover::before{background:rgba(0,0,0,.15)}.ui.slider.checkbox input:checked~label{color:rgba(0,0,0,.95)}.ui.slider.checkbox input:checked~label::before{background-color:#545454}.ui.slider.checkbox input:checked~label::after{left:2rem}.ui.slider.checkbox input:focus:checked~label{color:rgba(0,0,0,.95)}.ui.slider.checkbox input:focus:checked~label::before{background-color:#000}.ui.right.aligned.slider.checkbox label{padding-left:0;padding-right:4.5rem}.ui.right.aligned.slider.checkbox label::after{left:auto;right:2rem;transition:right .3s ease}.ui.right.aligned.slider.checkbox input:checked~label::after{left:auto;right:0}.ui.toggle.checkbox{min-height:1.5rem}.ui.toggle.checkbox input{width:3.5rem;height:1.5rem}.ui.toggle.checkbox label{min-height:1.5rem;padding-left:4.5rem;color:rgba(0,0,0,.87)}.ui.toggle.checkbox label{padding-top:.15em}.ui.toggle.checkbox label::before{display:block;position:absolute;content:"";z-index:1;transform:none;border:none;top:0;background:rgba(0,0,0,.05);box-shadow:none;width:3.5rem;height:1.5rem;border-radius:500rem}.ui.toggle.checkbox label::after{background:#fff linear-gradient(transparent,rgba(0,0,0,.05));position:absolute;content:""!important;opacity:1;z-index:2;border:none;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset;width:1.5rem;height:1.5rem;top:0;left:0;border-radius:500rem;transition:background .3s ease,left .3s ease}.ui.toggle.checkbox input~label::after{left:-.05rem;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset}.ui.toggle.checkbox input:focus~label::before{background-color:rgba(0,0,0,.15);border:none}.ui.toggle.checkbox label:hover::before{background-color:rgba(0,0,0,.15);border:none}.ui.toggle.checkbox input:checked~label{color:rgba(0,0,0,.95)}.ui.toggle.checkbox input:checked~label::before{background-color:#2185d0}.ui.toggle.checkbox input:checked~label::after{left:2.15rem;box-shadow:0 1px 2px 0 rgba(34,36,38,.15),0 0 0 1px rgba(34,36,38,.15) inset}.ui.toggle.checkbox input:focus:checked~label{color:rgba(0,0,0,.95)}.ui.toggle.checkbox input:focus:checked~label::before{background-color:#0d71bb}.ui.right.aligned.toggle.checkbox label{padding-left:0;padding-right:4.5rem}.ui.right.aligned.toggle.checkbox input~label::after{left:auto;right:2.15rem;transition:background .3s ease,right .3s ease}.ui.right.aligned.toggle.checkbox input:checked~label::after{left:auto;right:-.05rem}.ui.ui.fitted.checkbox label{padding-left:0}.ui.fitted.toggle.checkbox{width:3.5rem}.ui.fitted.slider.checkbox{width:3.5rem}.ui.ui.ui.inverted.checkbox label,.ui.ui.ui.inverted.checkbox+label{color:rgba(255,255,255,.9)}.ui.ui.inverted.checkbox label:hover{color:#fff}.ui.inverted.checkbox label:hover::before{border-color:rgba(34,36,38,.5)}.ui.inverted.slider.checkbox label{color:rgba(255,255,255,.5)}.ui.ui.inverted.slider.checkbox label::before{background-color:rgba(255,255,255,.5)}.ui.ui.inverted.slider.checkbox label:hover::before{background:rgba(255,255,255,.7)}.ui.ui.inverted.slider.checkbox input:checked~label{color:#fff}.ui.ui.inverted.slider.checkbox input:checked~label::before{background-color:rgba(255,255,255,.8)}.ui.ui.inverted.slider.checkbox input:focus:checked~label{color:#fff}.ui.ui.inverted.slider.checkbox input:focus:checked~label::before{background-color:rgba(255,255,255,.8)}.ui.ui.inverted.toggle.checkbox label::before{background-color:rgba(255,255,255,.9)}.ui.ui.inverted.toggle.checkbox label:hover::before{background:#fff}.ui.ui.inverted.toggle.checkbox input:checked~label{color:#fff}.ui.ui.inverted.toggle.checkbox input:checked~label::before{background-color:#2185d0}.ui.ui.inverted.toggle.checkbox input:focus:checked~label{color:#fff}.ui.ui.inverted.toggle.checkbox input:focus:checked~label::before{background-color:#0d71bb}.ui.invisible.checkbox:not(.compact){display:block}.ui.invisible.checkbox input{left:-99999px;position:absolute}.ui.invisible.checkbox label::after,.ui.invisible.checkbox label::before{display:none}.ui.invisible.checkbox label{transition:all .1s ease}.ui.ui.ui.ui.ui.invisible.checkbox input:not(:checked)+label{background:0 0;border-color:transparent;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset;color:inherit}.ui.ui.ui.ui.ui.invisible.checkbox input:not(:checked):not(:hover):focus+label:not(.image){box-shadow:0 0 0 1px rgba(34,36,38,.35) inset}.basic.ui.ui.ui.ui.ui.invisible.checkbox input:not(:checked)+label,.ui.ui.ui.ui.ui.invisible.checkbox input:not(:checked)+label.image{box-shadow:none}.ui.invisible.checkbox input:not(:checked)+label.image{opacity:.5;filter:grayscale(1)}.ui.invisible.checkbox input:not(:checked):not(:hover):focus+label.image{opacity:.75}.disabled.ui.invisible.checkbox input:not(:checked)+label.image,.ui.invisible.checkbox input:not(:checked)[disabled]+label.image{opacity:.25}.ui.mini.checkbox{font-size:.78571429em}.ui.tiny.checkbox{font-size:.85714286em}.ui.small.checkbox{font-size:.92857143em}.ui.large.checkbox{font-size:1.14285714em}.ui.large.checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.large.checkbox:not(.slider):not(.toggle):not(.radio) label::before,.ui.large.form .checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.large.form .checkbox:not(.slider):not(.toggle):not(.radio) label::before{transform:scale(1.14285714);transform-origin:left}.ui.large.checkbox.radio label::before,.ui.large.form .checkbox.radio label::before{transform:scale(1.14285714);transform-origin:left}.ui.large.checkbox.radio label::after,.ui.large.form .checkbox.radio label::after{transform:scale(.57142857);transform-origin:left;left:.33571429em}.ui.big.checkbox{font-size:1.28571429em}.ui.big.checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.big.checkbox:not(.slider):not(.toggle):not(.radio) label::before,.ui.big.form .checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.big.form .checkbox:not(.slider):not(.toggle):not(.radio) label::before{transform:scale(1.28571429);transform-origin:left}.ui.big.checkbox.radio label::before,.ui.big.form .checkbox.radio label::before{transform:scale(1.28571429);transform-origin:left}.ui.big.checkbox.radio label::after,.ui.big.form .checkbox.radio label::after{transform:scale(.64285714);transform-origin:left;left:.37142857em}.ui.huge.checkbox{font-size:1.42857143em}.ui.huge.checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.huge.checkbox:not(.slider):not(.toggle):not(.radio) label::before,.ui.huge.form .checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.huge.form .checkbox:not(.slider):not(.toggle):not(.radio) label::before{transform:scale(1.42857143);transform-origin:left}.ui.huge.checkbox.radio label::before,.ui.huge.form .checkbox.radio label::before{transform:scale(1.42857143);transform-origin:left}.ui.huge.checkbox.radio label::after,.ui.huge.form .checkbox.radio label::after{transform:scale(.71428571);transform-origin:left;left:.40714286em}.ui.massive.checkbox{font-size:1.71428571em}.ui.massive.checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.massive.checkbox:not(.slider):not(.toggle):not(.radio) label::before,.ui.massive.form .checkbox:not(.slider):not(.toggle):not(.radio) label::after,.ui.massive.form .checkbox:not(.slider):not(.toggle):not(.radio) label::before{transform:scale(1.71428571);transform-origin:left}.ui.massive.checkbox.radio label::before,.ui.massive.form .checkbox.radio label::before{transform:scale(1.71428571);transform-origin:left}.ui.massive.checkbox.radio label::after,.ui.massive.form .checkbox.radio label::after{transform:scale(.85714286);transform-origin:left;left:.47857143em}@font-face{font-family:Checkbox;src:url(data:application/font-woff;base64,d09GRgABAAAAAAR8AA0AAAAABtwAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAABGRlRNAAAEYAAAABoAAAAcgbCWJ0dERUYAAARIAAAAFwAAABgAJQAAT1MvMgAAAZgAAABAAAAAYA8SBD9jbWFwAAAB9AAAAFMAAAFc71zo6Wdhc3AAAARAAAAACAAAAAgAAAAQZ2x5ZgAAAlwAAADJAAABVHshwGBoZWFkAAABMAAAAC4AAAA2Bj3tWWhoZWEAAAFgAAAAHQAAACQHfQPIaG10eAAAAdgAAAAZAAAAHg56AEVsb2NhAAACSAAAABIAAAASAQoAjG1heHAAAAGAAAAAGAAAACAACgAvbmFtZQAAAygAAADnAAABp5xOC4Fwb3N0AAAEEAAAADAAAABaHRtWW3icY2BkYGBgYmDgqbAVjee3+crAzcIAAhc3XilHppl3M+cBKQ6QWgYGAAHnCVsAAHicY2BkYGA+8P8AAwMLAwgw72ZgZEAF7ABaJgNOAAAAeJxjYGRgYOBg0GUA0QwMTAxoAAAFtQA6eJxjYGYWYpzAwMrAwDST6QwDA0M/hGZ8zWDMyMmAChgF0AQYHBgYXjAxH/h/gMGB+QCIx8CIJKvAwAgAIOcKW3icY2GAAMZQCM0ExCwMDK7MqiAeAAqXAM4AAAB4nN2NwQ2AMAwDL00pHYJH52AQ9n/w6BbFCS9WwJFlO3IUwHl5YAQuJctcOaVdU6TGmGWt7IxJuHXnvmcrnLPR2GWb6NnF4rrwhT5U/o0Hf5EJGAAAAAAAAAgACAAQABgASABsAKoAAHichY09CsJAEIVndiG2gyQ7IASJIbHQyvyIiFhZpBE8iNsIeiVvYOFx7FPbKE6yUcHGgZ23jzd8DxDeowAWCv77Dez0Vd1hAIB+D714NMa0yNdYZrMhum0CfaWnT4bpeSPaEjOd8djIltTBNBlhSGzES3Jqb5oW6UOrE1WBL7/A73lxNBqnK8znZRbNWMgJET8qJhlWF1HV3zvXSceBSifawrTjTLrd0uI3c4lFu4UcYvbh1/KsIaodUayx7Kxr+wb8Y+EFi+YsngAAAHicfc5BSsNAGMXxf9q0agURFy50M3shlOoNikIXddGFa5N0SEvLDKQp2KUH8AxuXXkkz+JL+NYJJPzmffNmAlzxS0L7JJxzYx5wxoN5qPzZnMrv5hGXfJrHyr/NE+74UytJL5Rcdye0Huiue/NQ+aM5lV/NI27ZmsfKv8wTnvhhzgZPyY6CyAfMN77cFVFaaVBxZE9OraWvjvtc6Kn0jN40qDnoVyIBx4yMqWJfH7YxuFk27a2/dLVGxUpbQndYrrVnrazgpO9C1chSb7s3UymGxlU++Dpv/NoVJ7co4zLGkPEPj0VARQB4nGNgYsAPOBgYGJkYmBiZGZgZWRhZGdnYS/MyDYAAShuCaFcLCB9Iw/hGAOPdCuMAAQAB//8AD3icY2BkYGDgAWIBIGYCYhYIDQACOwAmAHicY2BgYGQAgns+by1A9MWNV8phNABQ5wfrAAA=) format("woff")}.ui.checkbox label::after{font-family:Checkbox}.ui.checkbox input:checked~label::after{content:"\e800"}.ui.checkbox input:indeterminate~label::after{font-size:12px;content:"\e801"} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.js b/internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.js new file mode 100755 index 0000000..61c15f3 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/checkbox.min.js @@ -0,0 +1,11 @@ +/* + * # Fomantic UI - 2.9.3 + * https://github.com/fomantic/Fomantic-UI + * https://fomantic-ui.com/ + * + * Copyright 2023 Contributors + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */ +!function(D,I,E){"use strict";function S(e){return"function"==typeof e&&"number"!=typeof e.nodeType}I=void 0!==I&&I.Math===Math?I:globalThis,D.fn.checkbox=function(s){var u,e=D(this),b=Date.now(),y=[],C=s,x="string"==typeof C,w=[].slice.call(arguments,1);return e.each(function(){var e,h=D.extend(!0,{},D.fn.checkbox.settings,s),n=h.className,i=h.namespace,g=h.selector,r=h.error,t="."+i,o="module-"+i,p=D(this),a=D(this).children(g.label),f=D(this).children(g.input),k=f[0],c=!1,m=!1,d=p.data(o),l=this,v={initialize:function(){v.verbose("Initializing checkbox",h),v.create.label(),v.bind.events(),v.set.tabbable(),v.hide.input(),v.observeChanges(),v.instantiate(),v.setup()},instantiate:function(){v.verbose("Storing instance of module",v),d=v,p.data(o,v)},destroy:function(){v.verbose("Destroying module"),v.unbind.events(),v.show.input(),p.removeData(o)},fix:{reference:function(){p.is(g.input)&&(v.debug("Behavior called on adjusting invoked element"),p=p.closest(g.checkbox),v.refresh())}},setup:function(){v.set.initialLoad(),v.is.indeterminate()?(v.debug("Initial value is indeterminate"),v.indeterminate()):v.is.checked()?(v.debug("Initial value is checked"),v.check()):(v.debug("Initial value is unchecked"),v.uncheck()),v.remove.initialLoad()},refresh:function(){a=p.children(g.label),f=p.children(g.input),k=f[0]},hide:{input:function(){v.verbose("Modifying z-index to be unselectable"),f.addClass(n.hidden)}},show:{input:function(){v.verbose("Modifying z-index to be selectable"),f.removeClass(n.hidden)}},observeChanges:function(){"MutationObserver"in I&&((e=new MutationObserver(function(e){v.debug("DOM tree modified, updating selector cache"),v.refresh()})).observe(l,{childList:!0,subtree:!0}),v.debug("Setting up mutation observer",e))},attachEvents:function(e,n){var i=D(e);n=S(v[n])?v[n]:v.toggle,0").insertAfter(f),v.debug("Creating label",a))}},has:{label:function(){return 0.comments{margin:0 0 .5em .5em;padding:1em 0 1em 1em}.ui.comments .comment>.comments::before{position:absolute;top:0;left:0}.ui.comments .comment>.comments .comment{border:none;border-top:none;background:0 0}.ui.comments .comment .avatar{display:block;width:2.5em;height:auto;float:left;margin:.2em 0 0}.ui.comments .comment .avatar img,.ui.comments .comment img.avatar{display:block;margin:0 auto;width:100%;height:100%;border-radius:.25rem}.ui.comments .comment>.content{display:block}.ui.comments .comment>.avatar~.content{margin-left:3.5em}.ui.comments .comment .author{font-size:1em;color:rgba(0,0,0,.87);font-weight:700}.ui.comments .comment a.author{cursor:pointer}.ui.comments .comment a.author:hover{color:#1e70bf}.ui.comments .comment .metadata{display:inline-block;margin-left:.5em;color:rgba(0,0,0,.4);font-size:.875em}.ui.comments .comment .metadata>*{display:inline-block;margin:0 .5em 0 0}.ui.comments .comment .metadata>:last-child{margin-right:0}.ui.comments .comment .text{margin:.25em 0 .5em;font-size:1em;word-wrap:break-word;color:rgba(0,0,0,.87);line-height:1.3}.ui.comments .comment .actions{font-size:.875em}.ui.comments .comment .actions a{cursor:pointer;display:inline-block;margin:0 .75em 0 0;color:rgba(0,0,0,.4)}.ui.comments .comment .actions a:last-child{margin-right:0}.ui.comments .comment .actions a.active,.ui.comments .comment .actions a:hover{color:rgba(0,0,0,.8)}.ui.comments>.reply.form{margin-top:1em}.ui.comments .comment .reply.form{width:100%;margin-top:1em}.ui.comments .reply.form textarea{font-size:1em;height:12em}.ui.collapsed.comments,.ui.comments .collapsed.comment,.ui.comments .collapsed.comments{display:none}.ui.threaded.comments .comment>.comments{margin:-1.5em 0 -1em 1.25em;padding:3em 0 2em 2.25em;box-shadow:-1px 0 0 rgba(34,36,38,.15)}.ui.minimal.comments .comment .actions{opacity:0;position:absolute;top:0;right:0;left:auto;transition:opacity .2s ease;transition-delay:.1s}.ui.minimal.comments .comment>.content:hover>.actions{opacity:1}.ui.comments{font-size:1rem}.ui.mini.comments{font-size:.78571429rem}.ui.tiny.comments{font-size:.85714286rem}.ui.small.comments{font-size:.92857143rem}.ui.large.comments{font-size:1.14285714rem}.ui.big.comments{font-size:1.28571429rem}.ui.huge.comments{font-size:1.42857143rem}.ui.massive.comments{font-size:1.71428571rem}.ui.inverted.comments .comment{background-color:#1b1c1d}.ui.inverted.comments .comment .author,.ui.inverted.comments .comment .text{color:rgba(255,255,255,.9)}.ui.inverted.comments .comment .actions a,.ui.inverted.comments .comment .metadata{color:rgba(255,255,255,.7)}.ui.inverted.comments .comment .actions a.active,.ui.inverted.comments .comment .actions a:hover,.ui.inverted.comments .comment a.author:hover{color:#fff}.ui.inverted.threaded.comments .comment>.comments{box-shadow:-1px 0 0 #555}.ui.comments .disabled.comment,.ui.disabled.comments{opacity:.45;pointer-events:none} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/container.min.css b/internal/app/server/static/dist/fomantic-ui.com/components/container.min.css new file mode 100755 index 0000000..2a31602 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/container.min.css @@ -0,0 +1,9 @@ +/*! + * # Fomantic-UI 2.9.3 - Container + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */.ui.container{display:block;max-width:100%}@media only screen and (max-width:767.98px){.ui.ui.ui.container:not(.fluid){width:auto;margin-left:1em;margin-right:1em}.ui.ui.ui.grid.container{width:auto}.ui.ui.ui.relaxed.grid.container{width:auto}.ui.ui.ui.very.relaxed.grid.container{width:auto}}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.ui.ui.container:not(.fluid){width:723px;margin-left:auto;margin-right:auto}.ui.ui.ui.grid.container{width:calc(723px + 2rem)}.ui.ui.ui.relaxed.grid.container{width:calc(723px + 3rem)}.ui.ui.ui.very.relaxed.grid.container{width:calc(723px + 5rem)}}@media only screen and (min-width:992px) and (max-width:1199.98px){.ui.ui.ui.container:not(.fluid){width:933px;margin-left:auto;margin-right:auto}.ui.ui.ui.grid.container{width:calc(933px + 2rem)}.ui.ui.ui.relaxed.grid.container{width:calc(933px + 3rem)}.ui.ui.ui.very.relaxed.grid.container{width:calc(933px + 5rem)}}@media only screen and (min-width:1200px){.ui.ui.ui.container:not(.fluid){width:1127px;margin-left:auto;margin-right:auto}.ui.ui.ui.grid.container{width:calc(1127px + 2rem)}.ui.ui.ui.relaxed.grid.container{width:calc(1127px + 3rem)}.ui.ui.ui.very.relaxed.grid.container{width:calc(1127px + 5rem)}}.ui.text.container{font-family:Lato,system-ui,-apple-system,"Segoe UI",Roboto,Oxygen,Ubuntu,Cantarell,"Helvetica Neue",Arial,"Noto Sans","Liberation Sans",sans-serif,"Apple Color Emoji","Segoe UI Emoji","Segoe UI Symbol","Noto Color Emoji";max-width:700px;line-height:1.5;font-size:1.14285714rem}@media only screen and (min-width:768px) and (max-width:991.98px){.ui.ui.ui.wide.container{width:867.6px}}@media only screen and (min-width:992px) and (max-width:1199.98px){.ui.ui.ui.wide.container{width:1119.6px}}@media only screen and (min-width:1200px){.ui.ui.ui.wide.container{width:1352.4px}}.ui.fluid.container{width:100%}.ui[class*="left aligned"].container{text-align:left}.ui[class*="center aligned"].container{text-align:center}.ui[class*="right aligned"].container{text-align:right}.ui.justified.container{text-align:justify;-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto}.ui.scrolling.container{overflow:auto;-ms-scroll-chaining:none;overscroll-behavior:none}@media only screen and (max-width:767.98px){.ui.scrolling.container.short{max-height:11.25em}.ui.scrolling.container.short.resizable{height:11.25em}.ui.scrolling.container[class*="very short"]{max-height:7.5em}.ui.scrolling.container[class*="very short"].resizable{height:7.5em}.ui.scrolling.container{max-height:15em}.ui.scrolling.container.long{max-height:30em}.ui.scrolling.container.long.resizable{height:30em}.ui.scrolling.container[class*="very long"]{max-height:45em}.ui.scrolling.container[class*="very long"].resizable{height:45em}}@media only screen and (min-width:768px){.ui.scrolling.container.short{max-height:13.5em}.ui.scrolling.container.short.resizable{height:13.5em}.ui.scrolling.container[class*="very short"]{max-height:9em}.ui.scrolling.container[class*="very short"].resizable{height:9em}.ui.scrolling.container{max-height:18em}.ui.scrolling.container.resizable{height:18em}.ui.scrolling.container.long{max-height:36em}.ui.scrolling.container.long.resizable{height:36em}.ui.scrolling.container[class*="very long"]{max-height:54em}.ui.scrolling.container[class*="very long"].resizable{height:54em}}@media only screen and (min-width:992px){.ui.scrolling.container.short{max-height:18em}.ui.scrolling.container.short.resizable{height:18em}.ui.scrolling.container[class*="very short"]{max-height:12em}.ui.scrolling.container[class*="very short"].resizable{height:12em}.ui.scrolling.container{max-height:24em}.ui.scrolling.container.resizable{height:24em}.ui.scrolling.container.long{max-height:48em}.ui.scrolling.container.long.resizable{height:48em}.ui.scrolling.container[class*="very long"]{max-height:72em}.ui.scrolling.container[class*="very long"].resizable{height:72em}}@media only screen and (min-width:1920px){.ui.scrolling.container.short{max-height:22.5em}.ui.scrolling.container.short.resizable{height:22.5em}.ui.scrolling.container[class*="very short"]{max-height:15em}.ui.scrolling.container[class*="very short"].resizable{height:15em}.ui.scrolling.container{max-height:30em}.ui.scrolling.container.resizable{height:30em}.ui.scrolling.container.long{max-height:60em}.ui.scrolling.container.long.resizable{height:60em}.ui.scrolling.container[class*="very long"]{max-height:90em}.ui.scrolling.container[class*="very long"].resizable{height:90em}}.ui.resizable.scrolling.container{resize:vertical;max-height:none} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.css b/internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.css new file mode 100755 index 0000000..7e9bcf7 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.css @@ -0,0 +1,9 @@ +/*! + * # Fomantic-UI 2.9.3 - Dimmer + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */.dimmable:not(body){position:relative}.ui.dimmer{display:none;position:absolute;top:0;left:0;width:100%;height:100%;text-align:center;vertical-align:middle;padding:1em;background:rgba(0,0,0,.85);opacity:0;line-height:1;animation-fill-mode:both;animation-duration:.5s;transition:all .5s linear;flex-direction:column;align-items:center;justify-content:center;-webkit-user-select:none;-ms-user-select:none;user-select:none;will-change:opacity;z-index:1000}.ui.dimmer>.content{-webkit-user-select:text;-ms-user-select:text;user-select:text;color:#fff}.ui.segment>.ui.dimmer:not(.page){border-radius:inherit}.ui.dimmer:not(.inverted)::-webkit-scrollbar-track{background:rgba(255,255,255,.1)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb{background:rgba(255,255,255,.25)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:window-inactive{background:rgba(255,255,255,.15)}.ui.dimmer:not(.inverted)::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.35)}.ui.dimmer:not(.inverted){scrollbar-face-color:#656565;scrollbar-shadow-color:#656565;scrollbar-track-color:#323232;scrollbar-arrow-color:#323232;scrollbar-color:rgba(255,255,255,.25) rgba(255,255,255,.1)}.animating.dimmable:not(body),.dimmed.dimmable:not(body){overflow:hidden}.dimmed.dimmable>.ui.animating.dimmer,.dimmed.dimmable>.ui.visible.dimmer,.ui.active.dimmer{display:flex;opacity:1}.ui.disabled.dimmer{width:0!important;height:0!important}.dimmed.dimmable>.ui.animating.legacy.dimmer,.dimmed.dimmable>.ui.visible.legacy.dimmer,.ui.active.legacy.dimmer{display:block}.ui[class*="top aligned"].dimmer{justify-content:flex-start}.ui[class*="bottom aligned"].dimmer{justify-content:flex-end}.ui.page.dimmer{position:fixed;transform-style:"";perspective:2000px;transform-origin:center center}.ui.page.dimmer.modals{-moz-perspective:none}body.animating.in.dimmable,body.dimmed.dimmable{overflow:hidden}body.dimmable>.dimmer{position:fixed}@supports (not (-webkit-backdrop-filter:none)) and (not ((-webkit-backdrop-filter:none) or (backdrop-filter:none))){.blurring.dimmable>:not(.dimmer){filter:initial;transition:.8s filter ease}.blurring.dimmed.dimmable>:not(.dimmer):not(.popup){filter:blur(5px) grayscale(.7)}}.blurring.dimmable>.dimmer{background:rgba(0,0,0,.6);-webkit-backdrop-filter:blur(5px) grayscale(.7);backdrop-filter:blur(5px) grayscale(.7)}.blurring.dimmable>.inverted.dimmer{background:rgba(255,255,255,.6)}.ui.dimmer>.top.aligned.content>*{vertical-align:top}.ui.dimmer>.bottom.aligned.content>*{vertical-align:bottom}.medium.medium.medium.medium.medium.dimmer{background:rgba(0,0,0,.65)}.light.light.light.light.light.dimmer{background:rgba(0,0,0,.45)}.very.very.very.very.light.dimmer{background:rgba(0,0,0,.25)}.ui.inverted.dimmer{background:rgba(255,255,255,.85)}.ui.inverted.dimmer>.content,.ui.inverted.dimmer>.content>*{color:#000}.medium.medium.medium.medium.medium.inverted.dimmer{background:rgba(255,255,255,.65)}.light.light.light.light.light.inverted.dimmer{background:rgba(255,255,255,.45)}.very.very.very.very.light.inverted.dimmer{background:rgba(255,255,255,.25)}.ui.simple.dimmer{display:block;overflow:hidden;opacity:0;width:0;height:0;z-index:-100;background:rgba(0,0,0,0)}.dimmed.dimmable>.ui.simple.dimmer{overflow:visible;opacity:1;width:100%;height:100%;background:rgba(0,0,0,.85);z-index:1}.ui.simple.inverted.dimmer{background:rgba(255,255,255,0)}.dimmed.dimmable>.ui.simple.inverted.dimmer{background:rgba(255,255,255,.85)}.ui[class*="bottom dimmer"],.ui[class*="center dimmer"],.ui[class*="top dimmer"]{height:auto}.ui[class*="bottom dimmer"]{top:auto;bottom:0}.ui[class*="center dimmer"]{top:50%;transform:translateY(-50%)}.ui.segment>.ui.ui[class*="top dimmer"]{border-bottom-left-radius:0;border-bottom-right-radius:0}.ui.segment>.ui.ui[class*="center dimmer"]{border-radius:0}.ui.segment>.ui.ui[class*="bottom dimmer"]{border-top-left-radius:0;border-top-right-radius:0}.ui[class*="center dimmer"].transition[class*="fade up"].in{animation-name:fadeInUpCenter}.ui[class*="center dimmer"].transition[class*="fade down"].in{animation-name:fadeInDownCenter}.ui[class*="center dimmer"].transition[class*="fade up"].out{animation-name:fadeOutUpCenter}.ui[class*="center dimmer"].transition[class*="fade down"].out{animation-name:fadeOutDownCenter}.ui[class*="center dimmer"].bounce.transition{animation-name:bounceCenter}@keyframes fadeInUpCenter{0%{opacity:0;transform:translateY(-40%)}100%{opacity:1;transform:translateY(-50%)}}@keyframes fadeInDownCenter{0%{opacity:0;transform:translateY(-60%)}100%{opacity:1;transform:translateY(-50%)}}@keyframes fadeOutUpCenter{0%{opacity:1;transform:translateY(-50%)}100%{opacity:0;transform:translateY(-45%)}}@keyframes fadeOutDownCenter{0%{opacity:1;transform:translateY(-50%)}100%{opacity:0;transform:translateY(-55%)}}@keyframes bounceCenter{0%,100%,20%,50%,80%{transform:translateY(-50%)}40%{transform:translateY(calc(-50% - 30px))}60%{transform:translateY(calc(-50% - 15px))}} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.js b/internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.js new file mode 100755 index 0000000..5782cb1 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/dimmer.min.js @@ -0,0 +1,11 @@ +/* + * # Fomantic UI - 2.9.3 + * https://github.com/fomantic/Fomantic-UI + * https://fomantic-ui.com/ + * + * Copyright 2023 Contributors + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */ +!function(x,e,T){"use strict";function S(e){return"function"==typeof e&&"number"!=typeof e.nodeType}e=void 0!==e&&e.Math===Math?e:globalThis,x.fn.dimmer=function(g){var v,b=x(this),p=Date.now(),h=[],y=g,C="string"==typeof y,w=[].slice.call(arguments,1);return b.each(function(){var o,i,a=x.isPlainObject(g)?x.extend(!0,{},x.fn.dimmer.settings,g):x.extend({},x.fn.dimmer.settings),n=a.selector,e=a.namespace,t=a.className,d=a.error,r="."+e,s="module-"+e,m="ontouchstart"in T.documentElement?"touchstart":"click",l=x(this),c=this,u=l.data(s),f={preinitialize:function(){o=f.is.dimmer()?(i=l.parent(),l):(i=l,f.has.dimmer()?a.dimmerName?i.find(n.dimmer).filter("."+a.dimmerName):i.find(n.dimmer):f.create())},initialize:function(){f.debug("Initializing dimmer",a),f.bind.events(),f.set.dimmable(),f.instantiate()},instantiate:function(){f.verbose("Storing instance of module",f),u=f,l.data(s,u)},destroy:function(){f.verbose("Destroying previous module",o),f.unbind.events(),f.remove.variation(),i.off(r)},bind:{events:function(){"hover"===a.on?i.on("mouseenter"+r,f.show).on("mouseleave"+r,f.hide):"click"===a.on&&i.on(m+r,f.toggle),f.is.page()&&(f.debug("Setting as a page dimmer",i),f.set.pageDimmer()),f.is.closable()&&(f.verbose("Adding dimmer close event",o),i.on(m+r,n.dimmer,f.event.click))}},unbind:{events:function(){l.removeData(s),i.off(r)}},event:{click:function(e){f.verbose("Determining if event occurred on dimmer",e),0!==o.find(e.target).length&&!x(e.target).is(n.content)||(f.hide(),e.stopImmediatePropagation())}},addContent:function(e){e=x(e);f.debug("Add content to dimmer",e),e.parent()[0]!==o[0]&&e.detach().appendTo(o)},create:function(){var e=x(a.template.dimmer(a));return a.dimmerName&&(f.debug("Creating named dimmer",a.dimmerName),e.addClass(a.dimmerName)),e.appendTo(i),e},show:function(e){e=S(e)?e:function(){},f.is.dimmed()&&!f.is.animating()||!f.is.enabled()?f.debug("Dimmer is already shown or disabled"):!1===a.onShow.call(c)?f.verbose("Show callback returned false cancelling dimmer show"):(f.debug("Showing dimmer",o,a),f.set.variation(),f.animate.show(e),a.onChange.call(c))},hide:function(e){e=S(e)?e:function(){},f.is.dimmed()||f.is.animating()?!1===a.onHide.call(c)?f.verbose("Hide callback returned false cancelling dimmer hide"):(f.debug("Hiding dimmer",o),f.animate.hide(e),a.onChange.call(c)):f.debug("Dimmer is not visible")},toggle:function(){f.verbose("Toggling dimmer visibility",o),f.is.dimmed()?f.is.closable()&&f.hide():f.show()},animate:{show:function(e){e=S(e)?e:function(){},a.useCSS&&void 0!==x.fn.transition?(a.useFlex?(f.debug("Using flex dimmer"),f.remove.legacy()):(f.debug("Using legacy non-flex dimmer"),f.set.legacy()),"auto"!==a.opacity&&f.set.opacity(),o.transition({debug:a.debug,verbose:a.verbose,silent:a.silent,displayType:a.useFlex?"flex":"block",animation:(a.transition.showMethod||a.transition)+" in",queue:!1,duration:f.get.duration(),useFailSafe:!0,onStart:function(){f.set.dimmed()},onComplete:function(){f.set.active(),a.onVisible.call(o),e()}})):(f.verbose("Showing dimmer animation with javascript"),f.set.dimmed(),"auto"===a.opacity&&(a.opacity=.8),o.stop().css({opacity:0,width:"100%",height:"100%"}).fadeTo(f.get.duration(),a.opacity,function(){o.removeAttr("style"),f.set.active(),a.onVisible.call(o),e()}))},hide:function(e){e=S(e)?e:function(){},a.useCSS&&void 0!==x.fn.transition?(f.verbose("Hiding dimmer with css"),o.transition({debug:a.debug,verbose:a.verbose,silent:a.silent,displayType:a.useFlex?"flex":"block",animation:(a.transition.hideMethod||a.transition)+" out",queue:!1,duration:f.get.duration(),useFailSafe:!0,onComplete:function(){f.remove.dimmed(),f.remove.variation(),f.remove.active(),a.onHidden.call(o),e()}})):(f.verbose("Hiding dimmer with javascript"),o.stop().fadeOut(f.get.duration(),function(){f.remove.dimmed(),f.remove.active(),o.removeAttr("style"),a.onHidden.call(o),e()}))}},get:{dimmer:function(){return o},duration:function(){return f.is.active()?a.transition.hideDuration||a.duration.hide||a.duration:a.transition.showDuration||a.duration.show||a.duration}},has:{dimmer:function(){return a.dimmerName?0 .ui.dimmer",content:".ui.dimmer > .content, .ui.dimmer > .content > .center"},template:{dimmer:function(e){var i,n=x("
").addClass("ui dimmer");return e.displayLoader&&(i=x("
").addClass(e.className.loader).addClass(e.loaderVariation),e.loaderText&&(i.text(e.loaderText),i.addClass("text")),n.append(i)),n}}}}(jQuery,window,document); \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/divider.min.css b/internal/app/server/static/dist/fomantic-ui.com/components/divider.min.css new file mode 100755 index 0000000..ce66c91 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/divider.min.css @@ -0,0 +1,9 @@ +/*! + * # Fomantic-UI 2.9.3 - Divider + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */.ui.divider{margin:1rem 0;line-height:1;height:0;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:rgba(0,0,0,.85);-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ui.divider:not(.vertical):not(.horizontal){border-top:1px solid rgba(34,36,38,.15);border-bottom:1px solid rgba(255,255,255,.1)}.ui.grid>.column+.divider,.ui.grid>.row>.column+.divider{left:auto}.ui.horizontal.divider{display:table;white-space:nowrap;height:auto;margin:"";line-height:1;text-align:center}.ui.horizontal.divider::after,.ui.horizontal.divider::before{content:"";display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.horizontal.divider::before{background-position:right 1em top 50%}.ui.horizontal.divider::after{background-position:left 1em top 50%}.ui.vertical.divider{position:absolute;z-index:2;top:50%;left:50%;margin:0;padding:0;width:auto;height:50%;line-height:0;text-align:center;transform:translateX(-50%)}.ui.vertical.divider::after,.ui.vertical.divider::before{position:absolute;left:50%;content:"";z-index:3;border-left:1px solid rgba(34,36,38,.15);border-right:1px solid rgba(255,255,255,.1);width:0;height:calc(100% - 1rem)}.ui.vertical.divider::before{top:-100%}.ui.vertical.divider::after{top:auto;bottom:0}@media only screen and (max-width:767.98px){.ui.grid .stackable.row .ui.vertical.divider,.ui.stackable.grid .ui.vertical.divider{display:table;white-space:nowrap;height:auto;margin:"";overflow:hidden;line-height:1;text-align:center;position:static;top:0;left:0;transform:none}.ui.grid .stackable.row .ui.vertical.divider::after,.ui.grid .stackable.row .ui.vertical.divider::before,.ui.stackable.grid .ui.vertical.divider::after,.ui.stackable.grid .ui.vertical.divider::before{left:0;border-left:none;border-right:none;content:"";display:table-cell;position:relative;top:50%;width:50%;background-repeat:no-repeat}.ui.grid .stackable.row .ui.vertical.divider::before,.ui.stackable.grid .ui.vertical.divider::before{background-position:right 1em top 50%}.ui.grid .stackable.row .ui.vertical.divider::after,.ui.stackable.grid .ui.vertical.divider::after{background-position:left 1em top 50%}}.ui.divider>.icon{margin:0;font-size:1rem;height:1em;vertical-align:middle}.ui.horizontal.divider[class*="left aligned"]::before{display:none}.ui.horizontal.divider[class*="left aligned"]::after{width:100%}.ui.horizontal.divider[class*="right aligned"]::before{width:100%}.ui.horizontal.divider[class*="right aligned"]::after{display:none}.ui.hidden.divider{border-color:transparent!important}.ui.hidden.divider::after,.ui.hidden.divider::before{display:none}.ui.divider.inverted,.ui.horizontal.inverted.divider,.ui.vertical.inverted.divider{color:#fff}.ui.divider.inverted,.ui.divider.inverted::after,.ui.divider.inverted::before{border-color:rgba(34,36,38,.15) rgba(255,255,255,.15) rgba(255,255,255,.15) rgba(34,36,38,.15)!important}.ui.fitted.divider{margin:0}.ui.clearing.divider{clear:both}.ui.section.divider{margin-top:2rem;margin-bottom:2rem}.ui.divider{font-size:1rem}.ui.mini.divider{font-size:.78571429rem}.ui.tiny.divider{font-size:.85714286rem}.ui.small.divider{font-size:.92857143rem}.ui.large.divider{font-size:1.14285714rem}.ui.big.divider{font-size:1.28571429rem}.ui.huge.divider{font-size:1.42857143rem}.ui.massive.divider{font-size:1.71428571rem}.ui.horizontal.divider::after,.ui.horizontal.divider::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}@media only screen and (max-width:767px){.ui.grid .stackable.row .ui.vertical.divider::after,.ui.grid .stackable.row .ui.vertical.divider::before,.ui.stackable.grid .ui.vertical.divider::after,.ui.stackable.grid .ui.vertical.divider::before{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABaAAAAACCAYAAACuTHuKAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyFpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChXaW5kb3dzKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDo1OThBRDY4OUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDo1OThBRDY4QUNDMTYxMUU0OUE3NUVGOEJDMzMzMjE2NyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOjU5OEFENjg3Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjU5OEFENjg4Q0MxNjExRTQ5QTc1RUY4QkMzMzMyMTY3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+VU513gAAADVJREFUeNrs0DENACAQBDBIWLGBJQby/mUcJn5sJXQmOQMAAAAAAJqt+2prAAAAAACg2xdgANk6BEVuJgyMAAAAAElFTkSuQmCC)}} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.css b/internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.css new file mode 100755 index 0000000..d5d5f24 --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.css @@ -0,0 +1,9 @@ +/*! + * # Fomantic-UI 2.9.3 - Dropdown + * https://github.com/fomantic/Fomantic-UI/ + * + * + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */.ui.dropdown{cursor:pointer;position:relative;display:inline-block;outline:0;text-align:left;transition:box-shadow .1s ease,width .1s ease;-webkit-user-select:none;-ms-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent}.ui.dropdown .menu{cursor:auto;position:absolute;display:none;outline:0;top:100%;min-width:-webkit-max-content;min-width:max-content;margin:0;padding:0;background:#fff;font-size:1em;text-shadow:none;text-align:left;box-shadow:0 2px 3px 0 rgba(34,36,38,.15);border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;transition:opacity .1s ease;z-index:11;will-change:transform,opacity}.ui.dropdown .menu>*{white-space:nowrap}.ui.dropdown>input:not(.search):first-child,.ui.dropdown>select{display:none!important}.ui.dropdown:not(.labeled)>.dropdown.icon{position:relative;width:auto;min-width:1em;font-size:.85714286em;margin:0 0 0 1em}.ui.dropdown .menu>.item .dropdown.icon{width:auto;float:right;margin:0 0 0 1em}.ui.dropdown .menu>.item .dropdown.icon+.text{margin-right:1em}.ui.dropdown>.text{display:inline-block;transition:none}.ui.dropdown .menu>.item{position:relative;cursor:pointer;display:block;border:none;height:auto;min-height:2.57142857rem;text-align:left;border-top:none;line-height:1em;font-size:1rem;color:rgba(0,0,0,.87);padding:.78571429rem 1.14285714rem;text-transform:none;font-weight:400;box-shadow:none;-webkit-touch-callout:none}.ui.dropdown .menu>.item:first-child{border-top-width:0}.ui.dropdown .menu>.item.vertical{display:flex;flex-direction:column-reverse}.ui.dropdown .menu .item>[class*="right floated"],.ui.dropdown>.text>[class*="right floated"]{float:right!important;margin-right:0!important;margin-left:1em!important}.ui.dropdown .menu .item>[class*="left floated"],.ui.dropdown>.text>[class*="left floated"]{float:left!important;margin-left:0!important;margin-right:1em!important}.ui.dropdown .menu .item>.flag.floated,.ui.dropdown .menu .item>.image.floated,.ui.dropdown .menu .item>i.icon.floated,.ui.dropdown .menu .item>img.floated{margin-top:0}.ui.dropdown .menu>.header{margin:1rem 0 .75rem;padding:0 1.14285714rem;font-weight:700;text-transform:uppercase}.ui.dropdown .menu>.header:not(.ui){color:rgba(0,0,0,.85);font-size:.78571429em}.ui.dropdown .menu>.divider{border-top:1px solid rgba(34,36,38,.1);height:0;margin:.5em 0}.ui.dropdown .menu>.horizontal.divider{border-top:none}.ui.ui.ui.dropdown .menu>.input{width:auto;display:flex;margin:1.14285714rem .78571429rem;min-width:10rem}.ui.dropdown .menu>.header+.input{margin-top:0}.ui.dropdown .menu>.input:not(.transparent) input{padding:.5em 1em}.ui.dropdown .menu>.input:not(.transparent) .button,.ui.dropdown .menu>.input:not(.transparent) .label,.ui.dropdown .menu>.input:not(.transparent) i.icon{padding-top:.5em;padding-bottom:.5em}.ui.dropdown .menu>.item>.description,.ui.dropdown>.text>.description{float:right;margin:0 0 0 1em;color:rgba(0,0,0,.4)}.ui.dropdown .menu>.item.vertical>.description{margin:0}.ui.dropdown .menu>.item.vertical>.text{margin-bottom:.25em}.ui.dropdown .menu>.message{padding:.78571429rem 1.14285714rem;font-weight:400}.ui.dropdown .menu>.message:not(.ui){color:rgba(0,0,0,.4)}.ui.dropdown .menu .menu{top:0;left:100%;right:auto;margin:0 -.5em!important;border-radius:.28571429rem!important;z-index:21!important}.ui.dropdown .menu .menu::after{display:none}.ui.dropdown>.text>.flag,.ui.dropdown>.text>.image,.ui.dropdown>.text>.label,.ui.dropdown>.text>i.icon,.ui.dropdown>.text>i.icons,.ui.dropdown>.text>img{margin-top:0}.ui.dropdown .menu>.item>.flag,.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>.label,.ui.dropdown .menu>.item>i.icon,.ui.dropdown .menu>.item>i.icons,.ui.dropdown .menu>.item>img{margin-top:0}.ui.dropdown .menu>.item>.flag,.ui.dropdown .menu>.item>.image,.ui.dropdown .menu>.item>.label,.ui.dropdown .menu>.item>i.icon,.ui.dropdown .menu>.item>i.icons,.ui.dropdown .menu>.item>img,.ui.dropdown>.text>.flag,.ui.dropdown>.text>.image,.ui.dropdown>.text>.label,.ui.dropdown>.text>i.icon,.ui.dropdown>.text>i.icons,.ui.dropdown>.text>img{margin-left:0;float:none;margin-right:.78571429rem}.ui.dropdown .menu>.item>.image:not(.icon),.ui.dropdown .menu>.item>img,.ui.dropdown>.text>.image:not(.icon),.ui.dropdown>.text>img{display:inline-block;vertical-align:top;width:auto;margin-top:-.5em;margin-bottom:-.5em;max-height:2em}.ui.dropdown .ui.menu>.item::before,.ui.menu .ui.dropdown .menu>.item::before{display:none}.ui.menu .ui.dropdown .menu .active.item{border-left:none}.ui.buttons>.ui.dropdown:last-child>.menu:not(.left),.ui.menu .right.dropdown.item>.menu:not(.left),.ui.menu .right.menu .dropdown:last-child>.menu:not(.left){left:auto;right:0}.ui.label.dropdown .menu{min-width:100%}.ui.dropdown.icon.button>.dropdown.icon{margin:0}.ui.dropdown.button .menu{min-width:100%}.ui.dropdown.button:not(.pointing):not(.floating).active{border-radius:.28571429rem .28571429rem 0 0}.ui.dropdown.button:not(.pointing):not(.floating)>.menu{border-radius:0 0 .28571429rem .28571429rem}select.ui.dropdown{height:38px;padding:.5em;border:1px solid rgba(34,36,38,.15);visibility:visible}.ui.selection.dropdown{cursor:pointer;word-wrap:break-word;line-height:1em;white-space:normal;outline:0;transform:rotateZ(0);min-width:14em;min-height:2.71428571em;background:#fff;display:inline-block;padding:.78571429em 3.2em .78571429em 1em;color:rgba(0,0,0,.87);box-shadow:none;border:1px solid rgba(34,36,38,.15);border-radius:.28571429rem;transition:box-shadow .1s ease,width .1s ease}.ui.selection.dropdown.active,.ui.selection.dropdown.visible{z-index:10}.ui.selection.dropdown>.delete.icon,.ui.selection.dropdown>.dropdown.icon,.ui.selection.dropdown>.search.icon{cursor:pointer;position:absolute;width:auto;height:auto;line-height:1.21428571em;top:.78571429em;right:1em;z-index:3;margin:-.78571429em;padding:.91666667em;opacity:.8;transition:opacity .1s ease}.ui.compact.selection.dropdown{min-width:0}.ui.compact.selection.dropdown>.menu{width:auto}.ui.compact.selection.dropdown>.menu:not(.multiline){width:-webkit-max-content;width:max-content}.ui.selection.dropdown:not(.unlimited) .menu{overflow-x:hidden;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:none;-webkit-backface-visibility:hidden;backface-visibility:hidden}.ui.selection.dropdown .menu{outline:0;margin:0 -1px;min-width:calc(100% + 2px);width:calc(100% + 2px);box-shadow:0 2px 3px 0 rgba(34,36,38,.15);transition:opacity .1s ease}.ui.selection.dropdown:not(.pointing):not(.floating) .menu{border-top-width:0;border-radius:0 0 .28571429rem .28571429rem}.ui.selection.dropdown .menu::after,.ui.selection.dropdown .menu::before{display:none}.ui.selection.dropdown .menu>.message{padding:.78571429rem 1.14285714rem}@media only screen and (max-width:767.98px){.ui.selection.dropdown.short .menu{max-height:6.01071429rem}.ui.selection.dropdown[class*="very short"] .menu{max-height:4.00714286rem}.ui.selection.dropdown:not(.unlimited) .menu{max-height:8.01428571rem}.ui.selection.dropdown.long .menu{max-height:16.02857143rem}.ui.selection.dropdown[class*="very long"] .menu{max-height:24.04285714rem}}@media only screen and (min-width:768px){.ui.selection.dropdown.short .menu{max-height:8.01428571rem}.ui.selection.dropdown[class*="very short"] .menu{max-height:5.34285714rem}.ui.selection.dropdown:not(.unlimited) .menu{max-height:10.68571429rem}.ui.selection.dropdown.long .menu{max-height:21.37142857rem}.ui.selection.dropdown[class*="very long"] .menu{max-height:32.05714286rem}}@media only screen and (min-width:992px){.ui.selection.dropdown.short .menu{max-height:12.02142857rem}.ui.selection.dropdown[class*="very short"] .menu{max-height:8.01428571rem}.ui.selection.dropdown:not(.unlimited) .menu{max-height:16.02857143rem}.ui.selection.dropdown.long .menu{max-height:32.05714286rem}.ui.selection.dropdown[class*="very long"] .menu{max-height:48.08571429rem}}@media only screen and (min-width:1920px){.ui.selection.dropdown.short .menu{max-height:16.02857143rem}.ui.selection.dropdown[class*="very short"] .menu{max-height:10.68571429rem}.ui.selection.dropdown:not(.unlimited) .menu{max-height:21.37142857rem}.ui.selection.dropdown.long .menu{max-height:42.74285714rem}.ui.selection.dropdown[class*="very long"] .menu{max-height:64.11428571rem}}.ui.selection.dropdown .menu>.item{border-top:1px solid #fafafa;padding:.78571429rem 1.14285714rem;white-space:normal;word-wrap:normal}.ui.selection.floating.dropdown .menu>.item:first-child,.ui.selection.pointing.dropdown .menu>.item:first-child{border-top:none}.ui.selection.dropdown .menu>.hidden.addition.item{display:none}.ui.dropdown>.menu>.stuck.addition.item:first-child{position:sticky;top:0;box-shadow:0 2px 3px 0 rgba(34,36,38,.15);background:#fff;z-index:14}.ui.selection.dropdown:hover{border-color:rgba(34,36,38,.35);box-shadow:none}.ui.selection.active.dropdown,.ui.selection.simple.dropdown:hover{border-color:#96c8da;box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.active.dropdown .menu,.ui.selection.simple.dropdown:hover .menu{border-color:#96c8da;box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.dropdown:focus{border-color:#96c8da;box-shadow:none}.ui.selection.dropdown:focus .menu{border-color:#96c8da;box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.visible.dropdown>.text:not(.default){font-weight:400;color:rgba(0,0,0,.8)}.ui.selection.active.dropdown:hover{border-color:#96c8da;box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.selection.active.dropdown:hover .menu{border-color:#96c8da;box-shadow:0 2px 3px 0 rgba(34,36,38,.15)}.ui.active.selection.dropdown>.dropdown.icon,.ui.visible.selection.dropdown>.dropdown.icon{opacity:"";z-index:3}.ui.active.selection.dropdown:not(.pointing):not(.floating){border-bottom-left-radius:0!important;border-bottom-right-radius:0!important}.ui.active.empty.selection.dropdown{border-radius:.28571429rem!important;box-shadow:none!important}.ui.active.empty.selection.dropdown .menu{border:none!important;box-shadow:none!important}@supports (-webkit-touch-callout:none) or (-moz-appearance:none){@media (-moz-touch-enabled),(pointer:coarse){.ui.dropdown .scrollhint.menu:not(.hidden)::before{animation:scrollhint 2s ease 2;content:"";z-index:15;display:block;position:absolute;opacity:0;right:.25em;top:0;height:100%;border-right:.25em solid;border-left:0;border-image:linear-gradient(to bottom,rgba(0,0,0,.75),rgba(0,0,0,0)) 1 100%}.ui.inverted.dropdown .scrollhint.menu:not(.hidden)::before{border-image:linear-gradient(to bottom,rgba(255,255,255,.75),rgba(255,255,255,0)) 1 100%}@keyframes scrollhint{0%{opacity:1;top:100%}100%{opacity:0;top:0}}}}.ui.search.dropdown{min-width:""}.ui.search.dropdown>input.search{background:none transparent!important;border:none!important;box-shadow:none!important;cursor:text;top:0;left:1px;width:100%;outline:0;-webkit-tap-highlight-color:rgba(255,255,255,0);padding:inherit}.ui.search.dropdown>input.search{position:absolute;z-index:2}.ui.search.dropdown>.text{cursor:text;position:relative;left:1px;z-index:auto}.ui.search.selection.dropdown>input.search{line-height:1.21428571em;padding:.67857143em 3.2em .67857143em 1em}.ui.search.selection.dropdown>span.sizer{line-height:1.21428571em;padding:.67857143em 3.2em .67857143em 1em;display:none;white-space:pre}.ui.search.dropdown.active>input.search,.ui.search.dropdown.visible>input.search{cursor:auto}.ui.search.dropdown.active>.text,.ui.search.dropdown.visible>.text{pointer-events:none}.ui.active.search.dropdown input.search:focus+.text .flag,.ui.active.search.dropdown input.search:focus+.text i.icon{opacity:.45}.ui.active.search.dropdown input.search:focus+.text{color:rgba(115,115,115,.87)!important}.ui.search.dropdown.button>span.sizer{display:none}.ui.search.dropdown:not(.unlimited) .menu{overflow-x:hidden;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:none;-webkit-backface-visibility:hidden;backface-visibility:hidden}@media only screen and (max-width:767.98px){.ui.search.dropdown:not(.unlimited) .menu{max-height:8.01428571rem}}@media only screen and (min-width:768px){.ui.search.dropdown:not(.unlimited) .menu{max-height:10.68571429rem}}@media only screen and (min-width:992px){.ui.search.dropdown:not(.unlimited) .menu{max-height:16.02857143rem}}@media only screen and (min-width:1920px){.ui.search.dropdown:not(.unlimited) .menu{max-height:21.37142857rem}}.ui.dropdown>.remove.icon{cursor:pointer;font-size:.85714286em;margin:-.78571429em;padding:.91666667em;right:2em;top:.78571429em;position:absolute;opacity:.6;z-index:3}.ui.selection.dropdown>.remove.icon{right:3em}.ui.inline.dropdown>.remove.icon{right:2.2em}.ui.clearable.dropdown .text,.ui.clearable.dropdown a:last-of-type{margin-right:1.5em}.ui.dropdown input:not([value])~.remove.icon,.ui.dropdown input[value=""]~.remove.icon,.ui.dropdown select.noselection~.remove.icon,.ui.dropdown.loading>.remove.icon{display:none}.ui.dropdown:not(.selection)>.remove.icon~.dropdown.icon{margin-left:1.5em}.ui.dropdown:not(.selection):not(.multiple)>.remove.icon{margin-top:-1.35em}.ui.ui.multiple.dropdown{padding:.22619048em 3.2em .22619048em .35714286em}.ui.multiple.dropdown .menu{cursor:auto}.ui.multiple.dropdown>.label{display:inline-block;white-space:normal;font-size:1em;padding:.35714286em .78571429em;margin:.14285714rem .28571429rem .14285714rem 0;box-shadow:0 0 0 1px rgba(34,36,38,.15) inset}.ui.multiple.dropdown .dropdown.icon{margin:"";padding:""}.ui.multiple.dropdown>.text{position:static;padding:0;max-width:100%;margin:.45238095em 0 .45238095em .64285714em;line-height:1.21428571em}.ui.multiple.dropdown>.text.default{white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.ui.multiple.dropdown>.label~input.search{margin-left:.14285714em!important}.ui.multiple.dropdown>.label~.text{display:none}.ui.multiple.dropdown>.label:not(.image)>img:not(.centered){margin-right:.78571429rem}.ui.multiple.dropdown>.label:not(.image)>img.ui:not(.avatar){margin-bottom:.39285714rem}.ui.multiple.dropdown>.image.label img{margin:-.35714286em .78571429em -.35714286em -.78571429em;height:1.71428571em}.ui.multiple.dropdown:not(.selection):not(.labeled)>.dropdown.icon{right:-1.5em}.ui.multiple.dropdown:not(.selection):not(.labeled)>.remove.icon{margin-right:-1.5em}.ui.multiple.dropdown:not(.selection):not(.labeled):not(.search)>.remove.icon~.text.default,.ui.multiple.dropdown:not(.selection):not(.labeled)>.text.default:first-child{overflow:inherit}.ui.multiple.search.dropdown,.ui.multiple.search.dropdown>input.search{cursor:text}.ui.multiple.search.dropdown>.text{display:inline-block;position:absolute;top:0;left:0;padding:inherit;margin:.45238095em 0 .45238095em .64285714em;line-height:1.21428571em}.ui.multiple.search.dropdown>.label~.text{display:none}.ui.multiple.search.dropdown>input.search{position:static;padding:0;max-width:100%;margin:.45238095em 0 .45238095em .64285714em;width:2.2em;line-height:1.21428571em}.ui.multiple.search.dropdown.button{min-width:14em}.ui.multiple.search.dropdown>span.sizer{display:none}.ui.multiple.search.dropdown:not(.selection)>.remove.icon+input.search,.ui.multiple.search.dropdown:not(.selection)>input.search:first-child{min-width:5.05em}.ui.inline.dropdown{cursor:pointer;display:inline-block;color:inherit}.ui.inline.dropdown .dropdown.icon{margin:0 .21428571em;vertical-align:baseline}.ui.inline.dropdown>.text{font-weight:700}.ui.inline.dropdown .menu{cursor:auto;margin-top:.21428571em;border-radius:.28571429rem}.ui.dropdown .menu .active.item{background:0 0;font-weight:700;color:rgba(0,0,0,.95);box-shadow:none;z-index:12}.ui.dropdown .menu>.item:hover{background:#f2f2f2;color:rgba(0,0,0,.95);z-index:13}.ui.default.dropdown:not(.button)>.text,.ui.dropdown:not(.button)>.default.text{color:rgba(191,191,191,.87)}.ui.default.dropdown:not(.button)>input:focus~.text,.ui.dropdown:not(.button)>input:focus~.default.text{color:rgba(115,115,115,.87)}.ui.loading.dropdown>i.icon{height:1em!important}.ui.loading.selection.dropdown>i.icon{padding:1.5em 1.28571429em!important}.ui.loading.dropdown>i.icon::before{position:absolute;content:"";top:50%;left:50%;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;border-radius:500rem;border:.2em solid rgba(0,0,0,.1)}.ui.loading.dropdown>i.icon::after{position:absolute;content:"";top:50%;left:50%;box-shadow:0 0 0 1px transparent;margin:-.64285714em 0 0 -.64285714em;width:1.28571429em;height:1.28571429em;animation:loader .6s infinite linear;border:.2em solid #767676;border-radius:500rem}.ui.loading.dropdown.button>i.icon::after,.ui.loading.dropdown.button>i.icon::before{display:none}.ui.loading.dropdown>.text{transition:none}.ui.dropdown .loading.menu{display:block;visibility:hidden;z-index:-1}.ui.dropdown>.loading.menu{left:0!important;right:auto!important}.ui.dropdown>.menu .loading.menu{left:100%!important;right:auto!important}.ui.dropdown .menu .selected.item,.ui.dropdown.selected{background:#f7f7f7;color:rgba(0,0,0,.95)}.ui.dropdown>.filtered.text{visibility:hidden}.ui.dropdown .filtered.item{display:none!important}.ui.dropdown.error,.ui.dropdown.error>.default.text,.ui.dropdown.error>.text{color:#9f3a38}.ui.selection.dropdown.error{background:#fff6f6;border-color:#e0b4b4}.ui.selection.dropdown.error:hover{border-color:#e0b4b4}.ui.multiple.selection.error.dropdown>.label{border-color:#e0b4b4}.ui.dropdown.error>.menu,.ui.dropdown.error>.menu .menu{border-color:#e0b4b4}.ui.dropdown.error>.menu>.item{color:#9f3a38}.ui.dropdown.error>.menu>.item:hover{background-color:#fbe7e7}.ui.dropdown.error>.menu .active.item{background-color:#fdcfcf}.ui.dropdown.info,.ui.dropdown.info>.default.text,.ui.dropdown.info>.text{color:#276f86}.ui.selection.dropdown.info{background:#f8ffff;border-color:#a9d5de}.ui.selection.dropdown.info:hover{border-color:#a9d5de}.ui.multiple.selection.info.dropdown>.label{border-color:#a9d5de}.ui.dropdown.info>.menu,.ui.dropdown.info>.menu .menu{border-color:#a9d5de}.ui.dropdown.info>.menu>.item{color:#276f86}.ui.dropdown.info>.menu>.item:hover{background-color:#e9f2fb}.ui.dropdown.info>.menu .active.item{background-color:#cef1fd}.ui.dropdown.success,.ui.dropdown.success>.default.text,.ui.dropdown.success>.text{color:#2c662d}.ui.selection.dropdown.success{background:#fcfff5;border-color:#a3c293}.ui.selection.dropdown.success:hover{border-color:#a3c293}.ui.multiple.selection.success.dropdown>.label{border-color:#a3c293}.ui.dropdown.success>.menu,.ui.dropdown.success>.menu .menu{border-color:#a3c293}.ui.dropdown.success>.menu>.item{color:#2c662d}.ui.dropdown.success>.menu>.item:hover{background-color:#e9fbe9}.ui.dropdown.success>.menu .active.item{background-color:#dafdce}.ui.dropdown.warning,.ui.dropdown.warning>.default.text,.ui.dropdown.warning>.text{color:#573a08}.ui.selection.dropdown.warning{background:#fffaf3;border-color:#c9ba9b}.ui.selection.dropdown.warning:hover{border-color:#c9ba9b}.ui.multiple.selection.warning.dropdown>.label{border-color:#c9ba9b}.ui.dropdown.warning>.menu,.ui.dropdown.warning>.menu .menu{border-color:#c9ba9b}.ui.dropdown.warning>.menu>.item{color:#573a08}.ui.dropdown.warning>.menu>.item:hover{background-color:#fbfbe9}.ui.dropdown.warning>.menu .active.item{background-color:#fdfdce}.ui.dropdown>.clear.dropdown.icon,.ui.dropdown>.remove.icon{opacity:.6;transition:opacity .1s ease}.ui.dropdown>.clear.dropdown.icon:hover,.ui.dropdown>.remove.icon:hover{opacity:1}.ui.disabled.dropdown,.ui.dropdown .menu>.disabled.item{cursor:default;pointer-events:none;opacity:.45}.ui.read-only.dropdown{cursor:default;pointer-events:none}.ui.disabled.dropdown>.label>.delete.icon,.ui.disabled.dropdown>.remove.icon,.ui.read-only.dropdown>.label>.delete.icon,.ui.read-only.dropdown>.remove.icon{display:none}.ui.dropdown .menu{left:0}.ui.dropdown .menu .right.menu,.ui.dropdown .right.menu>.menu{left:100%!important;right:auto!important;border-radius:.28571429rem!important}.ui.dropdown>.left.menu{left:auto!important;right:0!important}.ui.dropdown .menu .left.menu,.ui.dropdown>.left.menu .menu{left:auto;right:100%;margin:0 -.5em 0 0!important;border-radius:.28571429rem!important}.ui.dropdown .item .left.dropdown.icon,.ui.dropdown .left.menu .item .dropdown.icon{width:auto;float:left;margin:0}.ui.dropdown .item .left.dropdown.icon,.ui.dropdown .left.menu .item .dropdown.icon{width:auto;float:left;margin:0}.ui.dropdown .item .left.dropdown.icon+.text,.ui.dropdown .left.menu .item .dropdown.icon+.text{margin-left:1em;margin-right:0}.ui.upward.dropdown>.menu{top:auto;bottom:100%;box-shadow:0 0 3px 0 rgba(0,0,0,.08)}.ui.dropdown .upward.menu{top:auto!important;bottom:0!important}.ui.simple.upward.active.dropdown,.ui.simple.upward.dropdown:hover{border-radius:0 0 .28571429rem .28571429rem}.ui.upward.dropdown.button:not(.pointing):not(.floating).active{border-radius:0 0 .28571429rem .28571429rem}.ui.upward.dropdown.button:not(.pointing):not(.floating)>.menu{border-radius:.28571429rem .28571429rem 0 0}.ui.ui.upward.selection.dropdown:not(.pointing):not(.floating) .menu{border-top-width:1px;border-bottom-width:0;box-shadow:0 -2px 3px 0 rgba(0,0,0,.08);border-radius:.28571429rem .28571429rem 0 0}.ui.upward.selection.dropdown:hover{box-shadow:0 0 2px 0 rgba(0,0,0,.05)}.ui.active.upward.selection.dropdown:not(.pointing):not(.floating){border-radius:0 0 .28571429rem .28571429rem!important}.ui.upward.selection.dropdown.visible{box-shadow:0 0 3px 0 rgba(0,0,0,.08)}.ui.upward.selection.dropdown.visible:not(.pointing):not(.floating){border-radius:0 0 .28571429rem .28571429rem!important}.ui.upward.active.selection.dropdown:hover{box-shadow:0 0 3px 0 rgba(0,0,0,.05)}.ui.upward.active.selection.dropdown:hover:not(.pointing):not(.floating) .menu{box-shadow:0 -2px 3px 0 rgba(0,0,0,.08)}.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{overflow-x:hidden;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:none;-webkit-backface-visibility:hidden;backface-visibility:hidden;min-width:100%!important;width:auto!important}.ui.dropdown .scrolling.menu{position:static;border:none;box-shadow:none!important;border-radius:0 0 .28571429rem .28571429rem!important;margin:0!important;border-top:1px solid rgba(34,36,38,.15)}.ui.ui.ui.dropdown .scrolling.menu>.item,.ui.ui.ui.scrolling.dropdown .menu .item{border-top:none}.ui.dropdown .scrolling.menu .item:first-child,.ui.scrolling.dropdown .menu .item:first-child{border-top:none}.ui.dropdown>.animating.menu .scrolling.menu,.ui.dropdown>.visible.menu .scrolling.menu{display:block}@media all and (-ms-high-contrast:none){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{min-width:calc(100% - 17px)}}@media only screen and (max-width:767.98px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:10.28571429rem}.ui.dropdown .scrolling.resizable.menu,.ui.scrolling.resizable.dropdown .menu{height:10.28571429rem}}@media only screen and (min-width:768px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:15.42857143rem}.ui.dropdown .scrolling.resizable.menu,.ui.scrolling.resizable.dropdown .menu{height:15.42857143rem}}@media only screen and (min-width:992px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:20.57142857rem}.ui.dropdown .scrolling.resizable.menu,.ui.scrolling.resizable.dropdown .menu{height:20.57142857rem}}@media only screen and (min-width:1920px){.ui.dropdown .scrolling.menu,.ui.scrolling.dropdown .menu{max-height:20.57142857rem}.ui.dropdown .scrolling.resizable.menu,.ui.scrolling.resizable.dropdown .menu{height:20.57142857rem}}.ui.dropdown .scrolling.resizable.menu,.ui.scrolling.resizable.dropdown .menu{resize:vertical;max-height:none}.ui.labeled.input:not([class*="corner labeled"]) .label:first-child+.dropdown{border-top-left-radius:0;border-bottom-left-radius:0;border-left-color:transparent}.ui[class*="right labeled"].input>.dropdown:not(:last-child){border-top-right-radius:0!important;border-bottom-right-radius:0!important;border-right-color:transparent!important}.ui[class*="right labeled"].input>.dropdown+.label{border-top-left-radius:0;border-bottom-left-radius:0}.ui.column.dropdown>.menu{flex-wrap:wrap}.ui.dropdown[class*="two column"]>.menu>.item{width:50%}.ui.dropdown[class*="three column"]>.menu>.item{width:33%}.ui.dropdown[class*="four column"]>.menu>.item{width:25%}.ui.dropdown[class*="five column"]>.menu>.item{width:20%}.ui.simple.dropdown .menu::after,.ui.simple.dropdown .menu::before{display:none}.ui.simple.dropdown .menu{position:absolute;display:-ms-inline-flexbox!important;display:block;overflow:hidden;top:-9999px;opacity:0;width:0;height:0;transition:opacity .1s ease;margin-top:0!important}.ui.simple.dropdown .upward.menu{margin-bottom:1.5em}.ui.simple.selection.dropdown .upward.menu{margin-bottom:2.5em}.ui.menu:not(.vertical) .ui.simple.dropdown.item .upward.menu{margin-bottom:2.8em}.ui.simple.active.dropdown,.ui.simple.dropdown:hover{border-bottom-left-radius:0;border-bottom-right-radius:0}.ui.simple.active.dropdown>.menu,.ui.simple.dropdown:hover>.menu{overflow:visible;width:auto;height:auto;top:100%;opacity:1}.ui.simple.dropdown .menu .item:hover>.menu,.ui.simple.dropdown>.menu>.item:active>.menu{overflow:visible;width:auto;height:auto;top:0!important;left:100%;opacity:1}.ui.simple.selection.active.dropdown>.menu,.ui.simple.selection.dropdown .menu .item:hover>.menu,.ui.simple.selection.dropdown:hover>.menu,.ui.simple.selection.dropdown>.menu>.item:active>.menu{overflow:auto;-ms-scroll-chaining:none;overscroll-behavior:none}.right.menu .ui.simple.dropdown>.menu .item:hover>.menu:not(.right),.right.menu .ui.simple.dropdown>.menu>.item:active>.menu:not(.right),.ui.simple.dropdown .menu .item:hover>.left.menu,.ui.simple.dropdown>.menu>.item:active>.left.menu{left:auto;right:100%}.ui.simple.disabled.dropdown:hover .menu{display:none;height:0;width:0;overflow:hidden}.ui.simple.visible.dropdown>.menu{display:block}.ui.simple.scrolling.active.dropdown>.menu,.ui.simple.scrolling.dropdown:hover>.menu{overflow-x:hidden;overflow-y:auto;-ms-scroll-chaining:none;overscroll-behavior:none}.ui.fluid.dropdown{display:block;width:100%!important;min-width:0}.ui.fluid.dropdown>.dropdown.icon{float:right}.ui.floating.dropdown>.menu{left:0;right:auto;box-shadow:0 2px 4px 0 rgba(34,36,38,.12),0 2px 10px 0 rgba(34,36,38,.15)!important;border-radius:.28571429rem!important}.ui:not(.upward).floating.dropdown>.menu{margin-top:.5em}.ui.upward.floating.dropdown:not(.simple)>.menu{margin-bottom:.5em}.ui.pointing.dropdown>.menu{top:100%;margin-top:.78571429rem;border-radius:.28571429rem}.ui.pointing.dropdown>.menu:not(.hidden)::after{display:block;position:absolute;pointer-events:none;content:"";visibility:visible;transform:rotate(45deg);width:.5em;height:.5em;box-shadow:-1px -1px 0 0 rgba(34,36,38,.15);background:#fff;z-index:2}@supports selector(:has(.f)){.ui.pointing.dropdown:not(.upward) .menu:has(:first-child:hover)::after,.ui.upward.pointing.dropdown .menu:has(:last-child:hover)::after{background:#f2f2f2}.ui.pointing.dropdown:not(.upward) .menu:has(.selected.item:first-child)::after,.ui.upward.pointing.dropdown .menu:has(.selected.item:last-child)::after{background:#f7f7f7}}.ui.selection.pointing.dropdown>.menu::after{box-shadow:-1px -1px 0 0 #96c8da}.ui.pointing.dropdown>.menu:not(.hidden)::after{top:-.25em;left:50%;margin:0 0 0 -.25em}.ui.top.left.pointing.dropdown>.menu{top:100%;bottom:auto;left:0;right:auto;margin:1em 0 0}.ui.top.left.pointing.dropdown>.menu{top:100%;bottom:auto;left:0;right:auto;margin:1em 0 0}.ui.top.left.pointing.dropdown>.menu::after{top:-.25em;left:1em;right:auto;margin:0;transform:rotate(45deg)}.ui.top.right.pointing.dropdown>.menu{top:100%;bottom:auto;right:0;left:auto;margin:1em 0 0}.ui.top.pointing.dropdown>.left.menu::after,.ui.top.right.pointing.dropdown>.menu::after{top:-.25em;left:auto!important;right:1em!important;margin:0;transform:rotate(45deg)}.ui.left.pointing.dropdown>.menu{top:0;left:100%;right:auto;margin:0 0 0 1em}.ui.left.pointing.dropdown>.menu::after{top:1em;left:-.25em;margin:0;transform:rotate(-45deg)}.ui.left:not(.top):not(.bottom).pointing.dropdown>.left.menu{left:auto!important;right:100%!important;margin:0 1em 0 0}.ui.left:not(.top):not(.bottom).pointing.dropdown>.left.menu::after{top:1em;left:auto;right:-.25em;margin:0;transform:rotate(135deg)}.ui.right.pointing.dropdown>.menu{top:0;left:auto;right:100%;margin:0 1em 0 0}.ui.right.pointing.dropdown>.menu::after{top:1em;left:auto;right:-.25em;margin:0;transform:rotate(135deg)}.ui.bottom.pointing.dropdown>.menu{top:auto;bottom:100%;left:0;right:auto;margin:0 0 1em}.ui.bottom.pointing.dropdown>.menu::after{top:auto;bottom:-.25em;right:auto;margin:0;transform:rotate(-135deg)}.ui.bottom.pointing.dropdown>.menu .menu{top:auto!important;bottom:0!important}.ui.bottom.left.pointing.dropdown>.menu{left:0;right:auto}.ui.bottom.left.pointing.dropdown>.menu::after{left:1em;right:auto}.ui.bottom.right.pointing.dropdown>.menu{right:0;left:auto}.ui.bottom.right.pointing.dropdown>.menu::after{left:auto;right:1em}.ui.pointing.upward.dropdown .menu,.ui.top.pointing.upward.dropdown .menu{top:auto!important;bottom:100%!important;margin:0 0 .78571429rem;border-radius:.28571429rem}.ui.pointing.upward.dropdown .menu::after,.ui.top.pointing.upward.dropdown .menu::after{top:100%!important;bottom:auto!important;box-shadow:1px 1px 0 0 rgba(34,36,38,.15);margin:-.25em 0 0}.ui.selection.pointing.upward.dropdown .menu::after{box-shadow:1px 1px 0 0 #96c8da}.ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu{top:auto!important;bottom:0!important;margin:0 1em 0 0}.ui.right.pointing.upward.dropdown:not(.top):not(.bottom) .menu::after{top:auto!important;bottom:0!important;margin:0 0 1em 0;box-shadow:-1px -1px 0 0 rgba(34,36,38,.15)}.ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu{top:auto!important;bottom:0!important;margin:0 0 0 1em}.ui.left.pointing.upward.dropdown:not(.top):not(.bottom) .menu::after{top:auto!important;bottom:0!important;margin:0 0 1em 0;box-shadow:-1px -1px 0 0 rgba(34,36,38,.15)}.ui.floating.dropdown .menu .item:first-child,.ui.pointing.dropdown .menu .item:first-child{border-top-left-radius:.28571429rem;border-top-right-radius:.28571429rem}.ui.floating.dropdown .menu .item:last-child,.ui.pointing.dropdown .menu .item:last-child{border-bottom-left-radius:.28571429rem;border-bottom-right-radius:.28571429rem}.ui.dropdown,.ui.dropdown .menu>.item{font-size:1rem}.ui.mini.dropdown,.ui.mini.dropdown .menu>.item{font-size:.78571429rem}.ui.tiny.dropdown,.ui.tiny.dropdown .menu>.item{font-size:.85714286rem}.ui.small.dropdown,.ui.small.dropdown .menu>.item{font-size:.92857143rem}.ui.large.dropdown,.ui.large.dropdown .menu>.item{font-size:1.14285714rem}.ui.big.dropdown,.ui.big.dropdown .menu>.item{font-size:1.28571429rem}.ui.huge.dropdown,.ui.huge.dropdown .menu>.item{font-size:1.42857143rem}.ui.massive.dropdown,.ui.massive.dropdown .menu>.item{font-size:1.71428571rem}.ui.dropdown .inverted.menu,.ui.inverted.dropdown .menu{background:#1b1c1d;box-shadow:none;border:1px solid rgba(255,255,255,.15)}.ui.dropdown .inverted.menu>.item,.ui.inverted.dropdown .menu>.item{color:rgba(255,255,255,.8)}.ui.dropdown .inverted.menu .active.item,.ui.inverted.dropdown .menu .active.item{background:0 0;color:rgba(255,255,255,.8);box-shadow:none}.ui.dropdown .inverted.menu>.item:hover,.ui.inverted.dropdown .menu>.item:hover{background:#2d2e2f;color:rgba(255,255,255,.8)}.ui.dropdown .inverted.menu .selected.item,.ui.inverted.dropdown .menu .selected.item,.ui.inverted.dropdown.selected{background:#3d3e3f;color:rgba(255,255,255,.8)}.ui.dropdown .inverted.menu>.header,.ui.inverted.dropdown .menu>.header{color:#fff}.ui.dropdown .inverted.menu>.item>.description,.ui.inverted.dropdown .menu>.item>.description,.ui.inverted.dropdown>.text>.description{color:rgba(255,255,255,.5)}.ui.dropdown .inverted.menu>.divider,.ui.inverted.dropdown .menu>.divider{border-top:1px solid rgba(255,255,255,.15)}.ui.dropdown .inverted.scrolling.menu,.ui.inverted.dropdown .scrolling.menu{border:none;border-top:1px solid rgba(255,255,255,.15)}.ui.inverted.selection.dropdown{border:1px solid rgba(255,255,255,.15);background:#1b1c1d;color:rgba(255,255,255,.8)}.ui.inverted.selection.dropdown:hover{border-color:rgba(255,255,255,.25);box-shadow:none}.ui.inverted.selection.dropdown input{color:#fff}.ui.inverted.selection.visible.dropdown>.text:not(.default){color:rgba(255,255,255,.9)}.ui.inverted.selection.active.dropdown .menu,.ui.inverted.selection.active.dropdown:hover,.ui.inverted.selection.simple.dropdown:hover .menu,.ui.selection.active.dropdown .inverted.menu,.ui.selection.simple.dropdown:hover .inverted.menu{border-color:rgba(255,255,255,.15)}.ui.inverted.selection.dropdown .menu>.item,.ui.selection.dropdown .inverted.menu>.item{border-top:1px solid #242526}.ui.inverted.default.dropdown:not(.button)>.text,.ui.inverted.dropdown:not(.button)>.default.text{color:rgba(255,255,255,.5)}.ui.inverted.default.dropdown:not(.button)>input:focus~.text,.ui.inverted.dropdown:not(.button)>input:focus~.default.text{color:rgba(255,255,255,.7)}.ui.inverted.active.search.dropdown input.search:focus+.text .flag,.ui.inverted.active.search.dropdown input.search:focus+.text i.icon{opacity:.45}.ui.inverted.active.search.dropdown input.search:focus+.text{color:rgba(255,255,255,.7)!important}.ui.dropdown .inverted.menu>.message:not(.ui),.ui.inverted.dropdown .menu>.message:not(.ui){color:rgba(255,255,255,.5)}.ui.dropdown .inverted.menu>.item:first-child,.ui.inverted.dropdown .menu>.item:first-child{border-top-width:0}.ui.inverted.multiple.dropdown>.label{background-color:rgba(255,255,255,.7);background-image:none;color:#000;box-shadow:0 0 0 1px rgba(255,255,255,0) inset}.ui.inverted.multiple.dropdown>.label:hover{background-color:rgba(255,255,255,.9);border-color:rgba(255,255,255,.9);background-image:none;color:#000}.ui.inverted.multiple.dropdown>.label>.close.icon,.ui.inverted.multiple.dropdown>.label>.delete.icon{opacity:.6}.ui.inverted.multiple.dropdown>.label>.close.icon:hover,.ui.inverted.multiple.dropdown>.label>.delete.icon:hover{opacity:.8}.ui.inverted.dropdown input::selection,.ui.inverted.dropdown textarea::selection{background-color:rgba(255,255,255,.25);color:rgba(255,255,255,.8)}.ui.dropdown .inverted.menu::-webkit-scrollbar-track,.ui.inverted.dropdown .menu::-webkit-scrollbar-track{background:rgba(255,255,255,.1)}.ui.dropdown .inverted.menu::-webkit-scrollbar-thumb,.ui.inverted.dropdown .menu::-webkit-scrollbar-thumb{background:rgba(255,255,255,.25)}.ui.dropdown .inverted.menu::-webkit-scrollbar-thumb:window-inactive,.ui.inverted.dropdown .menu::-webkit-scrollbar-thumb:window-inactive{background:rgba(255,255,255,.15)}.ui.dropdown .inverted.menu::-webkit-scrollbar-thumb:hover,.ui.inverted.dropdown .menu::-webkit-scrollbar-thumb:hover{background:rgba(255,255,255,.35)}.ui.dropdown .inverted.menu,.ui.inverted.dropdown .menu{scrollbar-face-color:#656565;scrollbar-shadow-color:#656565;scrollbar-track-color:#323232;scrollbar-arrow-color:#323232;scrollbar-color:rgba(255,255,255,.25) rgba(255,255,255,.1)}.ui.inverted.pointing.dropdown>.menu::after,.ui.pointing.dropdown>.inverted.menu::after{background:#1b1c1d;box-shadow:-1px -1px 0 0 rgba(255,255,255,.15)}.ui.inverted.upward.pointing.dropdown>.menu::after{box-shadow:1px 1px 0 0 rgba(255,255,255,.15)}@supports selector(:has(.f)){.ui.inverted.pointing.dropdown:not(.upward) .menu:has(:first-child:hover)::after,.ui.inverted.upward.pointing.dropdown .menu:has(:last-child:hover)::after{background:#2d2e2f}.ui.inverted.pointing.dropdown:not(.upward) .menu:has(.selected.item:first-child)::after,.ui.inverted.upward.pointing.dropdown .menu:has(.selected.item:last-child)::after{background:#3d3e3f}}@font-face{font-family:Dropdown;src:url(data:application/font-woff;base64,d09GRk9UVE8AAASEAAsAAAAABwQAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAABDRkYgAAAC5AAAAU8AAAHrSr22AUZGVE0AAARQAAAAHAAAAByNrZ/TR0RFRgAABDQAAAAcAAAAIAAnABhPUy8yAAABYAAAAEIAAABgTadXCGNtYXAAAAKEAAAAVAAAAWQFcOKQaGVhZAAAAQgAAAAyAAAANg+j805oaGVhAAABPAAAABsAAAAkAwcBDWhtdHgAAARsAAAAFgAAAB4EAQASbWF4cAAAAVgAAAAGAAAABgAIUABuYW1lAAABpAAAAN8AAAG2rSbAM3Bvc3QAAALYAAAADAAAACAAAwAAeJxjYGRgYADiKjtG3nh+m68M3EwMIHCBwT0CRN9PyHYCUp6Mqox5QJqDASwNAMNOBrgAAHicY2BkYGB88P8BkFRlYACTjAyogB0AWWsDFgAAAFAAAAgAAHicY2Bm+Mg4gYGVgYHRhzGNgYHBHUp/ZZBkaGFABYwCSJyANNcUBgcGhg+3GB/8fwCUfMCgAFIDV6AAhIwAUbEMSQAAeJx1zTEKwkAUBNBJjIoKIggW2mwvBEVvIAgiNhY2VjEuQUh2YY2FeACPYOltvIH3cZJ8ywQS3p/d+QEwwAce/o8v9tDGUOzTU3GDXokD+ihuooeHuMX8Je5ijC9bXtCRP1T20Kcq+/RE3KAX4oDeipsYIRa3mD/FXSzxLtZeeGyR8bUwHGObWUvsoZHghhQRHEed3NLI1d+vyw/c43DleZErzBFixli768UaNQ9n9d11OedsJdxiyk0RZ40zsxPu/G7K7k66IUvW5CrRRrso12d1uqtNbHfcF+IHrnU+mwB4nGNgYGBmgGAZBkYGEIgD8hjBfBYGJyDNxcDBwASEjAwKH279//v/P1iVwofrYDbj/8dgPkQvGwMPkGRhYAWy2MHCbEDMxIAXMOOXHvIAAINhDt14nGNgZsALAAB9AAR4nE2Pv0rEQBCHZ3J7d4vGqEcOFaKC/zolZ6OWwmElNj6ClYWmyivcblyzE+RaK8EHsPMxBBtrwUdwA1fobpI7ZWBYfux8fD8ExgAR+fVVcpMkt4AeIAzLLSi3sdzxyt1WucqU31I+25iDtcvej1Kzh99V7+a19NoRPC1GAEsRvCxHwCP87MG8I7WgDRwWoAcrEMGmnT3YT+N0kB7G6Vk8PHLr2K0Tt04HB3FjMhUCQIESM7xDhfeYA3dcz5IZdOAcHuAD14MgeAu+zTNTRV5oTUR5obgZdwpVZFqQzEfKTiaE4JNwEralHGUuErnQNjE2oYxUwS0ldBTSxI3L7cOyKo60ib0lezSl1Rw+GXdq1pQiH03SdzKka4ymosLQTMcedSuIlEJUMqNcUi0jdIP5Ysb++leqLtSI/NWSTS0xq0WyYajQXPSVP/cLitO4NgB4nGNgZGBg4AFiAQYJBiYgzQLEIJoRggEFbQBAAAAAAQAAAADeTO04AAAAANAAR1gAAAAA32BrQnicY2BAAEYQVoVghu0MQgwMAAc/ARcAAA==) format("woff");font-weight:400;font-style:normal}.ui.dropdown>.dropdown.icon{font-family:Dropdown;line-height:1;height:1em;width:1.23em;-webkit-backface-visibility:hidden;backface-visibility:hidden;font-weight:400;font-style:normal;text-align:center}.ui.dropdown>.dropdown.icon{width:auto}.ui.dropdown>.dropdown.icon::before{content:"\f0d7"}.ui.dropdown .menu .item .dropdown.icon::before{content:"\f0da"}.ui.dropdown .item .left.dropdown.icon::before,.ui.dropdown .left.menu .item .dropdown.icon::before{content:"\f0d9"}.ui.vertical.menu .dropdown.item>.dropdown.icon::before{content:"\f0da"} \ No newline at end of file diff --git a/internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.js b/internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.js new file mode 100755 index 0000000..172a87f --- /dev/null +++ b/internal/app/server/static/dist/fomantic-ui.com/components/dropdown.min.js @@ -0,0 +1,11 @@ +/* + * # Fomantic UI - 2.9.3 + * https://github.com/fomantic/Fomantic-UI + * https://fomantic-ui.com/ + * + * Copyright 2023 Contributors + * Released under the MIT license + * https://opensource.org/licenses/MIT + * + */ +!function(ee,te,ne){"use strict";function ie(e){return"function"==typeof e&&"number"!=typeof e.nodeType}te=void 0!==te&&te.Math===Math?te:globalThis,ee.fn.dropdown=function(B){var W,Q=ee(this),Y=ee(ne),$=Date.now(),_=[],X=B,G="string"==typeof X,J=[].slice.call(arguments,1),Z=function(e,t){var n;return 0<=[te,ne].indexOf(e)?n=ee(e):0===(n=ee(t.document).find(e)).length&&(n=t.frameElement?Z(e,t.parent):te),n};return Q.each(function(z){var v,P,t,n,i,e,a,o,s,m=ee.isPlainObject(B)?ee.extend(!0,{},ee.fn.dropdown.settings,B):ee.extend({},ee.fn.dropdown.settings),h=m.className,f=m.message,l=m.fields,g=m.keys,p=m.metadata,F=m.namespace,r=m.regExp,b=m.selector,c=m.error,N=m.templates,d="."+F,u="module-"+F,w=ee(this),y=Z(m.context,te),C=w.find(b.text),x=w.find(b.search),S=w.find(b.sizer),A=w.find(b.input),H=w.find(b.icon),j=w.find(b.clearIcon),T=0").html(i).attr("data-"+p.value,t).attr("data-"+p.text,t).addClass(h.addition).addClass(h.item),m.hideAdditions&&i.addClass(h.hidden),n=void 0===n?i:n.add(i),M.verbose("Creating user choices for value",t,i))}),n)},userLabels:function(e){var t=M.get.userValues();t&&(M.debug("Adding user labels",t),ee.each(t,function(e,t){M.verbose("Adding custom user value"),M.add.label(t,t)}))},menu:function(){k=ee("
").addClass(h.menu).appendTo(w)},sizer:function(){S=ee("").addClass(h.sizer).insertAfter(x)}},search:function(e){e=void 0!==e?e:M.get.query(),M.verbose("Searching for query",e),!1===m.fireOnInit&&M.is.initialLoad()?M.verbose("Skipping callback on initial load",m.onSearch):M.has.minCharacters(e)&&!1!==m.onSearch.call(q,e)?M.filter(e):M.hide(null,!0)},select:{firstUnfiltered:function(){M.verbose("Selecting first non-filtered element"),M.remove.selectedItem(),L.not(b.unselectable).not(b.addition+b.hidden).eq(0).addClass(h.selected)},nextAvailable:function(e){var t=(e=e.eq(0)).nextAll(b.item).not(b.unselectable).eq(0),e=e.prevAll(b.item).not(b.unselectable).eq(0);0").addClass("remove icon").insertAfter(H)),M.is.search()&&!M.has.search()&&(M.verbose("Adding search input"),e=w.prev("label"),x=ee("").addClass(h.search).prop("autocomplete",M.is.chrome()?"fomantic-search":"off"),0").attr("class",A.attr("class")).addClass(h.selection).addClass(h.dropdown).html(N.dropdown(e,l,m.preserveHTML,m.className)).insertBefore(A),A.hasClass(h.multiple)&&!1===A.prop("multiple")&&(M.error(c.missingMultiple),A.prop("multiple",!0)),A.is("[multiple]")&&M.set.multiple(),A.prop("disabled")&&(M.debug("Disabling dropdown"),w.addClass(h.disabled)),A.is("[required]")&&(m.forceSelection=!0),m.allowTab||A.removeAttr("tabindex"),A.prop("required",!1).removeAttr("class").detach().prependTo(w)),M.refresh()},menu:function(e){k.html(N.menu(e,l,m.preserveHTML,m.className)),L=k.find(b.item),I=m.hideDividers?L.parent().children(b.divider):ee()},reference:function(){M.debug("Dropdown behavior was called on select, replacing with closest dropdown"),w=w.parent(b.dropdown),R=w.data(u),q=w[0],M.refresh(),M.setup.returnedObject()},returnedObject:function(){var e=Q.slice(0,z),t=Q.slice(z+1);Q=e.add(w).add(t)}},refresh:function(){M.refreshSelectors(),M.refreshData()},refreshItems:function(){L=k.find(b.item),I=m.hideDividers?L.parent().children(b.divider):ee()},refreshSelectors:function(){M.verbose("Refreshing selector cache"),C=w.find(b.text),x=w.find(b.search),A=w.find(b.input),H=w.find(b.icon),T=0"),ee.each(e,function(e,t){var n=m.templates.deQuote(t[l.value]),i=m.templates.escape(t[l.name]||"",m.preserveHTML);A.append('")}),M.observe.select())}},event:{paste:function(e){var t,n,i,a,o,s=(e.originalEvent.clipboardData||te.clipboardData).getData("text").split(m.delimiter),r=[];s.forEach(function(e){!1===M.set.selected(M.escape.htmlEntities(e.trim()),null,!1,!0)&&r.push(e.trim())}),e.preventDefault(),0 modified, recreating menu"),M.disconnect.selectObserver(),M.refresh(),M.setup.select(),M.set.selected(),M.observe.select())}},menu:{mutation:function(e){var e=e[0],t=e.addedNodes?ee(e.addedNodes[0]):ee(!1),e=e.removedNodes?ee(e.removedNodes[0]):ee(!1),t=t.add(e),e=t.is(b.addition)||0=m.maxSelections?(M.debug("Maximum selection count reached"),m.useLabels&&(L.addClass(h.filtered),M.add.message(f.maxSelections)),!0):(M.verbose("No longer at maximum selection count"),M.remove.message(),M.remove.filteredItem(),M.is.searchSelection()&&M.filterItems(),!1))},disabled:function(){x.attr("tabindex",M.is.disabled()?-1:0)}},restore:{defaults:function(e){M.clear(e),M.restore.defaultText(),M.restore.defaultValue()},defaultText:function(){var e=M.get.defaultText();e===M.get.placeholderText?(M.debug("Restoring default placeholder text",e),M.set.placeholderText(e)):(M.debug("Restoring default text",e),M.set.text(e))},placeholderText:function(){M.set.placeholderText()},defaultValue:function(){var e=M.get.defaultValue();void 0!==e&&(M.debug("Restoring default value",e),""!==e?(M.set.value(e),M.set.selected()):(M.remove.activeItem(),M.remove.selectedItem()))},labels:function(){m.allowAdditions&&(m.useLabels||(M.error(c.labels),m.useLabels=!0),M.debug("Restoring selected values"),M.create.userLabels()),M.check.maxSelections()},selected:function(){M.restore.values(),M.is.multiple()?(M.debug("Restoring previously selected values and labels"),M.restore.labels()):M.debug("Restoring previously selected values")},values:function(){M.set.initialLoad(),m.apiSettings&&m.saveRemoteData&&M.get.remoteValues()?M.restore.remoteValues():M.set.selected();var e=M.get.value();!e||""===e||Array.isArray(e)&&0===e.length?A.addClass(h.noselection):A.removeClass(h.noselection),M.remove.initialLoad()},remoteValues:function(){var e=M.get.remoteValues();M.debug("Recreating selected from session data",e),e&&(M.is.single()?ee.each(e,function(e,t){M.set.text(t)}):m.useLabels&&ee.each(e,function(e,t){M.add.label(e,t)}))}},read:{remoteData:function(e){if(void 0!==te.Storage)return void 0!==(e=sessionStorage.getItem(e+i))&&e;M.error(c.noStorage)}},save:{defaults:function(){M.save.defaultText(),M.save.placeholderText(),M.save.defaultValue()},defaultValue:function(){var e=M.get.value();M.verbose("Saving default value as",e),w.data(p.defaultValue,e)},defaultText:function(){var e=M.get.text();M.verbose("Saving default text as",e),w.data(p.defaultText,e)},placeholderText:function(){var e;!1!==m.placeholder&&C.hasClass(h.placeholder)&&(e=M.get.text(),M.verbose("Saving placeholder text as",e),w.data(p.placeholderText,e))},remoteData:function(e,t){void 0===te.Storage?M.error(c.noStorage):(M.verbose("Saving remote data to session storage",t,e),sessionStorage.setItem(t+i,e))}},clear:function(e){M.is.multiple()&&m.useLabels?M.remove.labels(w.find(b.label),e):(M.remove.activeItem(),M.remove.selectedItem(),M.remove.filteredItem()),M.set.placeholderText(),M.clearValue(e)},clearValue:function(e){M.set.value("",null,null,e)},clearCache:function(){M.debug("Clearing API cache once"),V=!0},scrollPage:function(e,t){var t=t||M.get.selectedItem(),n=t.closest(b.menu),i=n.outerHeight(),a=n.scrollTop(),o=L.eq(0).outerHeight(),i=Math.floor(i/o),a="up"===e?a-o*i:a+o*i,o=L.not(b.unselectable),i="up"===e?o.index(t)-i:o.index(t)+i,i=("up"===e?0<=i:i").addClass(h.label).attr("data-"+p.value,o).html(N.label(o,t,m.preserveHTML,m.className)),i=m.onLabelCreate.call(i,o,t),M.has.label(e)?M.debug("User selection already exists, skipping",o):(m.label.variation&&i.addClass(m.label.variation),!0===n&&m.label.transition?(M.debug("Animating in label",i),i.addClass(h.hidden).insertBefore(a).transition({animation:m.label.transition,debug:m.debug,verbose:m.verbose,silent:m.silent,duration:m.label.duration})):(M.debug("Adding selection label",i),i.insertBefore(a)))},message:function(e){var t=k.children(b.message),e=m.templates.message(M.add.variables(e));0").html(e).addClass(h.message).appendTo(k)},optionValue:function(e){var t=M.escape.value(e);0").prop("value",t).addClass(h.addition).text(e).appendTo(A),M.verbose("Adding user addition as an