├── .deepsource.toml
├── .eslintignore
├── .eslintrc
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
├── pull_request_template.md
└── workflows
│ ├── dev.yml
│ └── master.yml
├── .gitignore
├── .gitmodules
├── .husky
├── .gitignore
└── pre-commit
├── .prettierignore
├── .prettierrc
├── LICENCE
├── README.md
├── angular.json
├── docs
└── images
│ ├── calculate-hash-offline-github.png
│ ├── calculate-hash-offline.png
│ ├── calculate-hash-online-1.1.png
│ ├── calculate-hash-online-1.png
│ ├── calculate-hash-online-2.png
│ ├── calculate-hash-online-github.png
│ ├── calculate-hash-online-github1.png
│ ├── calculate-hash-online-github2.png
│ ├── electron-index-html-diff.png
│ ├── hash-online-raw-1.png
│ ├── right-click.png
│ ├── save-as-file.png
│ ├── save-as-html-only-file.png
│ └── save-github-file1.png
├── e2e
├── app.e2e-spec.ts
├── app.po.ts
└── tsconfig.e2e.json
├── electron-builder.json
├── electron-main.ts
├── electron-tsconfig.json
├── karma.conf.js
├── package-lock.json
├── package.json
├── patch-webpack.js
├── protractor.conf.js
├── src
├── CNAME
├── README.md
├── app
│ ├── app.component.html
│ ├── app.component.scss
│ ├── app.component.spec.ts
│ ├── app.component.ts
│ ├── app.error-handler.ts
│ ├── app.module.ts
│ ├── footer
│ │ ├── footer.component.html
│ │ ├── footer.component.scss
│ │ ├── footer.component.spec.ts
│ │ ├── footer.component.ts
│ │ ├── footer.module.spec.ts
│ │ └── footer.module.ts
│ ├── header
│ │ ├── header.component.html
│ │ ├── header.component.scss
│ │ ├── header.component.spec.ts
│ │ ├── header.component.ts
│ │ ├── header.module.spec.ts
│ │ └── header.module.ts
│ ├── mail
│ │ ├── dialogs
│ │ │ ├── create-folder
│ │ │ │ ├── create-folder.component.html
│ │ │ │ ├── create-folder.component.scss
│ │ │ │ └── create-folder.component.ts
│ │ │ ├── export-message
│ │ │ │ ├── export-message.component.html
│ │ │ │ ├── export-message.component.scss
│ │ │ │ ├── export-message.component.spec.ts
│ │ │ │ └── export-message.component.ts
│ │ │ ├── import-private-key
│ │ │ │ ├── import-private-key.component.html
│ │ │ │ ├── import-private-key.component.scss
│ │ │ │ ├── import-private-key.component.spec.ts
│ │ │ │ └── import-private-key.component.ts
│ │ │ └── payment-failure-notice
│ │ │ │ ├── payment-failure-notice.component.html
│ │ │ │ └── payment-failure-notice.component.ts
│ │ ├── mail-contact
│ │ │ ├── mail-contact.component.html
│ │ │ ├── mail-contact.component.scss
│ │ │ ├── mail-contact.component.spec.ts
│ │ │ ├── mail-contact.component.ts
│ │ │ └── save-contact
│ │ │ │ ├── save-contact.component.html
│ │ │ │ ├── save-contact.component.scss
│ │ │ │ ├── save-contact.component.spec.ts
│ │ │ │ └── save-contact.component.ts
│ │ ├── mail-detail
│ │ │ ├── mail-detail-body
│ │ │ │ ├── mail-detail-body.component.html
│ │ │ │ ├── mail-detail-body.component.scss
│ │ │ │ ├── mail-detail-body.component.spec.ts
│ │ │ │ └── mail-detail-body.component.ts
│ │ │ ├── mail-detail-decryption-error
│ │ │ │ ├── mail-detail-decryption-error.component.html
│ │ │ │ ├── mail-detail-decryption-error.component.scss
│ │ │ │ ├── mail-detail-decryption-error.component.spec.ts
│ │ │ │ └── mail-detail-decryption-error.component.ts
│ │ │ ├── mail-detail-encryption-type-icon
│ │ │ │ ├── mail-detail-encryption-type-icon.component.html
│ │ │ │ ├── mail-detail-encryption-type-icon.component.scss
│ │ │ │ ├── mail-detail-encryption-type-icon.component.spec.ts
│ │ │ │ └── mail-detail-encryption-type-icon.component.ts
│ │ │ ├── mail-detail-header
│ │ │ │ ├── mail-detail-header.component.html
│ │ │ │ ├── mail-detail-header.component.scss
│ │ │ │ ├── mail-detail-header.component.spec.ts
│ │ │ │ └── mail-detail-header.component.ts
│ │ │ ├── mail-detail-password-decryption-panel
│ │ │ │ ├── mail-detail-password-decryption-panel.component.html
│ │ │ │ ├── mail-detail-password-decryption-panel.component.scss
│ │ │ │ ├── mail-detail-password-decryption-panel.component.spec.ts
│ │ │ │ └── mail-detail-password-decryption-panel.component.ts
│ │ │ ├── mail-detail.component.html
│ │ │ ├── mail-detail.component.scss
│ │ │ ├── mail-detail.component.spec.ts
│ │ │ └── mail-detail.component.ts
│ │ ├── mail-footer
│ │ │ ├── mail-footer.component.html
│ │ │ ├── mail-footer.component.scss
│ │ │ ├── mail-footer.component.spec.ts
│ │ │ └── mail-footer.component.ts
│ │ ├── mail-header
│ │ │ ├── mail-header.component.html
│ │ │ ├── mail-header.component.scss
│ │ │ ├── mail-header.component.spec.ts
│ │ │ └── mail-header.component.ts
│ │ ├── mail-list
│ │ │ ├── mail-folder
│ │ │ │ └── generic-folder
│ │ │ │ │ ├── generic-folder.component.html
│ │ │ │ │ ├── generic-folder.component.scss
│ │ │ │ │ ├── generic-folder.component.spec.ts
│ │ │ │ │ └── generic-folder.component.ts
│ │ │ ├── mail-list.component.html
│ │ │ ├── mail-list.component.scss
│ │ │ ├── mail-list.component.spec.ts
│ │ │ └── mail-list.component.ts
│ │ ├── mail-routing.module.ts
│ │ ├── mail-settings
│ │ │ ├── addresses-signature
│ │ │ │ ├── addresses-signature.component.html
│ │ │ │ ├── addresses-signature.component.scss
│ │ │ │ ├── addresses-signature.component.spec.ts
│ │ │ │ └── addresses-signature.component.ts
│ │ │ ├── custom-domains
│ │ │ │ ├── custom-domains.component.html
│ │ │ │ ├── custom-domains.component.scss
│ │ │ │ ├── custom-domains.component.spec.ts
│ │ │ │ └── custom-domains.component.ts
│ │ │ ├── folders
│ │ │ │ ├── folders.component.html
│ │ │ │ ├── folders.component.scss
│ │ │ │ ├── folders.component.spec.ts
│ │ │ │ └── folders.component.ts
│ │ │ ├── invite-codes
│ │ │ │ ├── invite-codes.component.html
│ │ │ │ ├── invite-codes.component.scss
│ │ │ │ ├── invite-codes.component.spec.ts
│ │ │ │ └── invite-codes.component.ts
│ │ │ ├── mail-autoresponder
│ │ │ │ ├── mail-autoresponder.component.html
│ │ │ │ ├── mail-autoresponder.component.scss
│ │ │ │ └── mail-autoresponder.component.ts
│ │ │ ├── mail-filters
│ │ │ │ ├── mail-filters.component.html
│ │ │ │ └── mail-filters.component.ts
│ │ │ ├── mail-forwarding
│ │ │ │ ├── mail-forwarding.component.html
│ │ │ │ ├── mail-forwarding.component.scss
│ │ │ │ └── mail-forwarding.component.ts
│ │ │ ├── mail-settings.component.html
│ │ │ ├── mail-settings.component.scss
│ │ │ ├── mail-settings.component.spec.ts
│ │ │ ├── mail-settings.component.ts
│ │ │ ├── organization
│ │ │ │ ├── organization-dashboard
│ │ │ │ │ ├── organization-dashboard.component.html
│ │ │ │ │ ├── organization-dashboard.component.scss
│ │ │ │ │ ├── organization-dashboard.component.spec.ts
│ │ │ │ │ └── organization-dashboard.component.ts
│ │ │ │ ├── organization-editor
│ │ │ │ │ ├── organization-editor.component.html
│ │ │ │ │ ├── organization-editor.component.scss
│ │ │ │ │ ├── organization-editor.component.spec.ts
│ │ │ │ │ └── organization-editor.component.ts
│ │ │ │ ├── organization-users-list
│ │ │ │ │ ├── organization-users-list.component.html
│ │ │ │ │ ├── organization-users-list.component.scss
│ │ │ │ │ ├── organization-users-list.component.spec.ts
│ │ │ │ │ └── organization-users-list.component.ts
│ │ │ │ ├── organization-users
│ │ │ │ │ ├── organization-users.component.html
│ │ │ │ │ ├── organization-users.component.scss
│ │ │ │ │ ├── organization-users.component.spec.ts
│ │ │ │ │ └── organization-users.component.ts
│ │ │ │ └── organization-viewer
│ │ │ │ │ ├── organization-viewer.component.html
│ │ │ │ │ ├── organization-viewer.component.scss
│ │ │ │ │ ├── organization-viewer.component.spec.ts
│ │ │ │ │ └── organization-viewer.component.ts
│ │ │ ├── save-list-contact
│ │ │ │ ├── save-list-contact.component.html
│ │ │ │ ├── save-list-contact.component.scss
│ │ │ │ ├── save-list-contact.component.spec.ts
│ │ │ │ └── save-list-contact.component.ts
│ │ │ └── security
│ │ │ │ ├── security.component.html
│ │ │ │ ├── security.component.scss
│ │ │ │ ├── security.component.spec.ts
│ │ │ │ └── security.component.ts
│ │ ├── mail-sidebar
│ │ │ ├── compose-mail-dialog
│ │ │ │ ├── compose-mail-dialog.component.html
│ │ │ │ ├── compose-mail-dialog.component.scss
│ │ │ │ └── compose-mail-dialog.component.ts
│ │ │ ├── compose-mail
│ │ │ │ ├── compose-mail.component.html
│ │ │ │ ├── compose-mail.component.scss
│ │ │ │ ├── compose-mail.component.ts
│ │ │ │ ├── composer-encryption-type-icon
│ │ │ │ │ ├── composer-encryption-type-icon.component.html
│ │ │ │ │ ├── composer-encryption-type-icon.component.scss
│ │ │ │ │ ├── composer-encryption-type-icon.component.spec.ts
│ │ │ │ │ └── composer-encryption-type-icon.component.ts
│ │ │ │ └── receiver-email-chip
│ │ │ │ │ ├── receiver-email-chip.component.html
│ │ │ │ │ ├── receiver-email-chip.component.scss
│ │ │ │ │ ├── receiver-email-chip.component.spec.ts
│ │ │ │ │ └── receiver-email-chip.component.ts
│ │ │ ├── mail-sidebar.component.html
│ │ │ ├── mail-sidebar.component.scss
│ │ │ ├── mail-sidebar.component.spec.ts
│ │ │ └── mail-sidebar.component.ts
│ │ ├── mail.component.html
│ │ ├── mail.component.scss
│ │ ├── mail.component.spec.ts
│ │ ├── mail.component.ts
│ │ ├── mail.module.spec.ts
│ │ └── mail.module.ts
│ ├── pages
│ │ ├── pages-donate
│ │ │ ├── pages-donate.component.html
│ │ │ ├── pages-donate.component.scss
│ │ │ ├── pages-donate.component.spec.ts
│ │ │ ├── pages-donate.component.ts
│ │ │ └── payment-options
│ │ │ │ ├── payment-options.component.html
│ │ │ │ ├── payment-options.component.scss
│ │ │ │ ├── payment-options.component.spec.ts
│ │ │ │ └── payment-options.component.ts
│ │ ├── pages-routing.module.ts
│ │ └── pages.module.ts
│ ├── shared
│ │ ├── circle-bar-spinner
│ │ │ ├── circle-bar-spinner.component.html
│ │ │ ├── circle-bar-spinner.component.scss
│ │ │ ├── circle-bar-spinner.component.spec.ts
│ │ │ └── circle-bar-spinner.component.ts
│ │ ├── components
│ │ │ ├── advanced-search
│ │ │ │ ├── advanced-search.component.html
│ │ │ │ ├── advanced-search.component.scss
│ │ │ │ ├── advanced-search.component.spec.ts
│ │ │ │ └── advanced-search.component.ts
│ │ │ ├── bitcoin-form
│ │ │ │ ├── bitcoin-form.component.html
│ │ │ │ ├── bitcoin-form.component.scss
│ │ │ │ ├── bitcoin-form.component.spec.ts
│ │ │ │ └── bitcoin-form.component.ts
│ │ │ ├── countdown-timer
│ │ │ │ ├── countdown-timer.component.html
│ │ │ │ ├── countdown-timer.component.scss
│ │ │ │ └── countdown-timer.component.ts
│ │ │ ├── custom-dropdown
│ │ │ │ ├── custom-dropdown.component.html
│ │ │ │ ├── custom-dropdown.component.scss
│ │ │ │ └── custom-dropdown.component.ts
│ │ │ ├── loading-spinner
│ │ │ │ ├── loading-spinner.component.html
│ │ │ │ ├── loading-spinner.component.scss
│ │ │ │ └── loading-spinner.component.ts
│ │ │ ├── loading
│ │ │ │ ├── loading.component.html
│ │ │ │ ├── loading.component.scss
│ │ │ │ ├── loading.component.spec.ts
│ │ │ │ └── loading.component.ts
│ │ │ ├── pricing-plans
│ │ │ │ ├── pricing-plans.component.html
│ │ │ │ ├── pricing-plans.component.scss
│ │ │ │ └── pricing-plans.component.ts
│ │ │ ├── progress-bar
│ │ │ │ ├── progress-bar.component.html
│ │ │ │ ├── progress-bar.component.scss
│ │ │ │ └── progress-bar.component.ts
│ │ │ ├── spinner-image
│ │ │ │ ├── spinner-image.component.html
│ │ │ │ ├── spinner-image.component.scss
│ │ │ │ ├── spinner-image.component.spec.ts
│ │ │ │ └── spinner-image.component.ts
│ │ │ ├── stripe-form
│ │ │ │ ├── stripe-form.component.html
│ │ │ │ ├── stripe-form.component.scss
│ │ │ │ └── stripe-form.component.ts
│ │ │ └── users-billing-info
│ │ │ │ ├── users-billing-info.component.html
│ │ │ │ ├── users-billing-info.component.scss
│ │ │ │ ├── users-billing-info.component.spec.ts
│ │ │ │ └── users-billing-info.component.ts
│ │ ├── config.ts
│ │ ├── directives
│ │ │ ├── anchor-scroll.directive.ts
│ │ │ ├── click-outside.directive.ts
│ │ │ └── is-ie.directive.ts
│ │ ├── pipes
│ │ │ ├── creditcard-number.pipe.ts
│ │ │ ├── email-formatting.pipe.ts
│ │ │ ├── filename.pipe.ts
│ │ │ ├── filesize.pipe.ts
│ │ │ ├── fix-outlook-quotes.pipe.ts
│ │ │ ├── last-action.pipe.ts
│ │ │ ├── moment-date.pipe.ts
│ │ │ ├── remaining-time.pipe.ts
│ │ │ ├── replace-linebreak-brtag.pipe.ts
│ │ │ └── safe.pipe.ts
│ │ ├── services
│ │ │ ├── browser-detector.service.ts
│ │ │ ├── dynamic-script-loader.service.ts
│ │ │ ├── key-manage.service.spec.ts
│ │ │ ├── key-manage.service.ts
│ │ │ ├── logger.service.spec.ts
│ │ │ ├── logger.service.ts
│ │ │ ├── push-notification.service.spec.ts
│ │ │ ├── push-notification.service.ts
│ │ │ ├── theme-toggle-service.ts
│ │ │ ├── user-select-manage.service.spec.ts
│ │ │ ├── user-select-manage.service.ts
│ │ │ ├── websocket.service.spec.ts
│ │ │ └── websocket.service.ts
│ │ ├── shared.module.ts
│ │ ├── spinner
│ │ │ ├── components
│ │ │ │ ├── spinner.component.html
│ │ │ │ ├── spinner.component.scss
│ │ │ │ ├── spinner.component.spec.ts
│ │ │ │ └── spinner.component.ts
│ │ │ └── services
│ │ │ │ ├── spinner.service.spec.ts
│ │ │ │ └── spinner.service.ts
│ │ ├── util
│ │ │ ├── dom-utils.ts
│ │ │ └── utils.ts
│ │ └── validators
│ │ │ └── no-whitespace.validator.ts
│ ├── store
│ │ ├── actions
│ │ │ ├── auth.action.ts
│ │ │ ├── bitcoin.action.ts
│ │ │ ├── compose-mail.actions.ts
│ │ │ ├── contacts.action.ts
│ │ │ ├── donate.actions.ts
│ │ │ ├── index.ts
│ │ │ ├── keyboard.action.ts
│ │ │ ├── loading.action.ts
│ │ │ ├── mail.actions.ts
│ │ │ ├── organization.action.ts
│ │ │ ├── router.action.ts
│ │ │ ├── search.action.ts
│ │ │ ├── secure-message.actions.ts
│ │ │ ├── timezone.action.ts
│ │ │ └── users.action.ts
│ │ ├── datatypes.ts
│ │ ├── effects
│ │ │ ├── auth.effects.ts
│ │ │ ├── bitcoin.effects.ts
│ │ │ ├── compose-mail.effects.ts
│ │ │ ├── contacts.effects.ts
│ │ │ ├── donate.effects.ts
│ │ │ ├── index.ts
│ │ │ ├── mail.effects.ts
│ │ │ ├── mailbox.effects.ts
│ │ │ ├── organization.effects.ts
│ │ │ ├── router.effect.ts
│ │ │ ├── secure-message.effects.ts
│ │ │ ├── timezone.effects.ts
│ │ │ └── users.effects.ts
│ │ ├── index.ts
│ │ ├── models
│ │ │ ├── filter.model.ts
│ │ │ ├── index.ts
│ │ │ ├── mail.model.ts
│ │ │ └── users.model.ts
│ │ ├── quotes.ts
│ │ ├── reducers
│ │ │ ├── auth.reducers.ts
│ │ │ ├── bitcoin.reducers.ts
│ │ │ ├── compose-mail.reducers.ts
│ │ │ ├── contacts.reducers.ts
│ │ │ ├── donate.reducers.ts
│ │ │ ├── index.ts
│ │ │ ├── keyboard.reducers.ts
│ │ │ ├── loading.reducers.ts
│ │ │ ├── mail.reducers.ts
│ │ │ ├── mailboxes.reducers.ts
│ │ │ ├── organization.reducer.ts
│ │ │ ├── search.reducers.ts
│ │ │ ├── secure-message.reducers.ts
│ │ │ ├── timezone.reducer.ts
│ │ │ └── users.reducers.ts
│ │ ├── selectors
│ │ │ └── index.ts
│ │ ├── services
│ │ │ ├── auth.guard.ts
│ │ │ ├── autocrypt.process.service.ts
│ │ │ ├── bitcoin.service.ts
│ │ │ ├── breakpoint.service.ts
│ │ │ ├── cancel.request.interceptor.ts
│ │ │ ├── cancel.request.service.ts
│ │ │ ├── compose-mail.service.ts
│ │ │ ├── datetime-util.service.ts
│ │ │ ├── donation.service.ts
│ │ │ ├── electron.service.ts
│ │ │ ├── export-mail.service.ts
│ │ │ ├── index.ts
│ │ │ ├── mail-settings.service.ts
│ │ │ ├── mail.service.ts
│ │ │ ├── message.builder.service.ts
│ │ │ ├── message.decrypt.service.ts
│ │ │ ├── notification.service.ts
│ │ │ ├── openpgp.service.ts
│ │ │ ├── print-mail.service.ts
│ │ │ ├── shared.service.ts
│ │ │ ├── timezone.service.ts
│ │ │ ├── token.interceptor.ts
│ │ │ └── users.service.ts
│ │ ├── store.module.ts
│ │ └── websocket.store.ts
│ └── users
│ │ ├── decrypt
│ │ ├── decrypt-message.component.html
│ │ ├── decrypt-message.component.scss
│ │ └── decrypt-message.component.ts
│ │ ├── dialogs
│ │ ├── display-name-dialog
│ │ │ ├── display-name-dialog.component.html
│ │ │ ├── display-name-dialog.component.scss
│ │ │ ├── display-name-dialog.component.spec.ts
│ │ │ └── display-name-dialog.component.ts
│ │ ├── send-feedback-dialog
│ │ │ ├── send-feedback-dialog.component.html
│ │ │ ├── send-feedback-dialog.component.scss
│ │ │ ├── send-feedback-dialog.component.spec.ts
│ │ │ └── send-feedback-dialog.component.ts
│ │ ├── use-cache-dialog
│ │ │ ├── use-cache-dialog.component.html
│ │ │ ├── use-cache-dialog.component.scss
│ │ │ ├── use-cache-dialog.component.spec.ts
│ │ │ └── use-cache-dialog.component.ts
│ │ └── user-account-init-dialog
│ │ │ ├── user-account-init-dialog.component.html
│ │ │ ├── user-account-init-dialog.component.scss
│ │ │ ├── user-account-init-dialog.component.spec.ts
│ │ │ └── user-account-init-dialog.component.ts
│ │ ├── display-secure-message
│ │ ├── display-secure-message.component.html
│ │ ├── display-secure-message.component.scss
│ │ └── display-secure-message.component.ts
│ │ ├── reply-secure-message
│ │ ├── reply-secure-message.component.html
│ │ ├── reply-secure-message.component.scss
│ │ └── reply-secure-message.component.ts
│ │ ├── users-create-account
│ │ ├── users-create-account.component.html
│ │ ├── users-create-account.component.scss
│ │ ├── users-create-account.component.spec.ts
│ │ └── users-create-account.component.ts
│ │ ├── users-routing.module.ts
│ │ ├── users-sign-in
│ │ ├── users-sign-in.component.html
│ │ ├── users-sign-in.component.scss
│ │ ├── users-sign-in.component.spec.ts
│ │ └── users-sign-in.component.ts
│ │ ├── users-sign-up
│ │ ├── users-sign-up.component.html
│ │ ├── users-sign-up.component.scss
│ │ ├── users-sign-up.component.spec.ts
│ │ └── users-sign-up.component.ts
│ │ ├── users.module.spec.ts
│ │ └── users.module.ts
├── assets
│ ├── css
│ │ └── noscript-styles.css
│ ├── fonts
│ │ ├── ctemplar-fonts
│ │ │ ├── autocrypt.eot
│ │ │ ├── autocrypt.svg
│ │ │ ├── autocrypt.ttf
│ │ │ └── autocrypt.woff
│ │ ├── ctemplar
│ │ │ ├── ctemplar-icon-info-circle.eot
│ │ │ ├── ctemplar-icon-info-circle.svg
│ │ │ ├── ctemplar-icon-info-circle.ttf
│ │ │ └── ctemplar-icon-info-circle.woff
│ │ ├── icomoon
│ │ │ ├── icomoon.eot
│ │ │ ├── icomoon.svg
│ │ │ ├── icomoon.ttf
│ │ │ ├── icomoon.woff
│ │ │ └── libs
│ │ │ │ └── icomoon.zip
│ │ ├── lato
│ │ │ ├── S6u9w4BMUTPHh50XSwaPGQ3q5d0N7w.woff2
│ │ │ ├── S6u9w4BMUTPHh50XSwiPGQ3q5d0.woff2
│ │ │ ├── S6u9w4BMUTPHh6UVSwaPGQ3q5d0N7w.woff2
│ │ │ ├── S6u9w4BMUTPHh6UVSwiPGQ3q5d0.woff2
│ │ │ ├── S6uyw4BMUTPHjx4wXiWtFCc.woff2
│ │ │ ├── S6uyw4BMUTPHjxAwXiWtFCfQ7A.woff2
│ │ │ ├── flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2
│ │ │ └── fontsLato.css
│ │ └── webfonts
│ │ │ ├── Lato-Bold.eot
│ │ │ ├── Lato-Bold.svg
│ │ │ ├── Lato-Bold.ttf
│ │ │ ├── Lato-Bold.woff
│ │ │ ├── Lato-Italic.eot
│ │ │ ├── Lato-Italic.svg
│ │ │ ├── Lato-Italic.ttf
│ │ │ ├── Lato-Italic.woff
│ │ │ ├── Lato-Light.eot
│ │ │ ├── Lato-Light.svg
│ │ │ ├── Lato-Light.ttf
│ │ │ ├── Lato-Light.woff
│ │ │ ├── Lato-Regular.eot
│ │ │ ├── Lato-Regular.svg
│ │ │ ├── Lato-Regular.ttf
│ │ │ ├── Lato-Regular.woff
│ │ │ ├── Roboto-Bold.eot
│ │ │ ├── Roboto-Bold.svg
│ │ │ ├── Roboto-Bold.ttf
│ │ │ ├── Roboto-Bold.woff
│ │ │ ├── Roboto-Regular.eot
│ │ │ ├── Roboto-Regular.svg
│ │ │ ├── Roboto-Regular.ttf
│ │ │ ├── Roboto-Regular.woff
│ │ │ ├── fa-brands-400.eot
│ │ │ ├── fa-brands-400.svg
│ │ │ ├── fa-brands-400.ttf
│ │ │ ├── fa-brands-400.woff
│ │ │ ├── fa-brands-400.woff2
│ │ │ ├── fa-regular-400.eot
│ │ │ ├── fa-regular-400.svg
│ │ │ ├── fa-regular-400.ttf
│ │ │ ├── fa-regular-400.woff
│ │ │ ├── fa-regular-400.woff2
│ │ │ ├── fa-solid-900.eot
│ │ │ ├── fa-solid-900.svg
│ │ │ ├── fa-solid-900.ttf
│ │ │ ├── fa-solid-900.woff
│ │ │ ├── fa-solid-900.woff2
│ │ │ └── fortfa-brands-400.ttf
│ ├── i18n
│ │ ├── ar.json
│ │ ├── de.json
│ │ ├── en.json
│ │ ├── es.json
│ │ ├── fr.json
│ │ ├── it.json
│ │ ├── ja.json
│ │ ├── pl.json
│ │ ├── pt.json
│ │ ├── ro.json
│ │ ├── ru.json
│ │ ├── tr.json
│ │ ├── uk.json
│ │ └── zh.json
│ ├── icons
│ │ ├── favicon.ico
│ │ ├── icon.png
│ │ ├── icon@512.png
│ │ ├── spinner.svg
│ │ └── warranty-canary.png
│ ├── images
│ │ ├── account-creation-img.jpg
│ │ ├── all-emails.svg
│ │ ├── blog
│ │ │ ├── blog-banner.jpg
│ │ │ ├── blog-img-1.jpg
│ │ │ ├── blog-img-2.jpg
│ │ │ ├── blog-img-3.jpg
│ │ │ ├── blog-img-4.jpg
│ │ │ ├── blog-img-5.jpg
│ │ │ ├── blog-img-6.jpg
│ │ │ ├── table_d-min.png
│ │ │ ├── table_m_2x-min.png
│ │ │ └── table_t-min.png
│ │ ├── donate
│ │ │ ├── bitcoin.png
│ │ │ └── donate-by-card.png
│ │ ├── features-icon
│ │ │ ├── documents.svg
│ │ │ ├── lock.svg
│ │ │ ├── mobile.svg
│ │ │ ├── shield.svg
│ │ │ └── tower.svg
│ │ ├── home
│ │ │ ├── banner.png
│ │ │ └── hero-banner.png
│ │ ├── icon-mail.svg
│ │ ├── icon-reply-all.svg
│ │ ├── icon-reply.svg
│ │ ├── logo.svg
│ │ ├── logo_1.svg
│ │ ├── logo_2.svg
│ │ ├── logo_3.svg
│ │ ├── mail-unread.svg
│ │ ├── media-kit
│ │ │ ├── mediakit-logo-sec.png
│ │ │ ├── mediakit-logo1.png
│ │ │ ├── mediakit-logo1.svg
│ │ │ ├── mediakit-logo2.png
│ │ │ ├── mediakit-logo2.svg
│ │ │ ├── mediakit-logo3.png
│ │ │ ├── mediakit-logo3.svg
│ │ │ ├── mediakit-logo4.png
│ │ │ ├── mediakit-logo4.svg
│ │ │ ├── wallpaper-img1.jpg
│ │ │ ├── wallpaper-img2.jpg
│ │ │ ├── wallpaper-img3.jpg
│ │ │ ├── wallpaper-img4.jpg
│ │ │ ├── wallpaper-img5.jpg
│ │ │ ├── wallpaper-img6.jpg
│ │ │ ├── wallpaper-img7.jpg
│ │ │ └── wallpaper-img8.jpg
│ │ ├── more_horiz_black_20dp.png
│ │ ├── onions
│ │ │ ├── onions-img.png
│ │ │ └── tor.png
│ │ ├── outbox.svg
│ │ ├── plus@2x.png
│ │ ├── select-arrow.svg
│ │ ├── user-actions
│ │ │ ├── decrypt_message.png
│ │ │ └── login-bg.jpg
│ │ └── user-icon-grey.png
│ ├── js
│ │ ├── browser-compatibility.js
│ │ ├── ckeditor-build
│ │ │ ├── ckeditor.js
│ │ │ └── ckeditor.js.map
│ │ ├── scrambler.min.js
│ │ ├── stripe-key.js
│ │ └── stripe-test-key.js
│ └── static
│ │ ├── email.html
│ │ ├── info-circle.png
│ │ ├── logo.svg
│ │ ├── pgp-worker.js
│ │ ├── pricing-plans.json
│ │ └── starter-email.html
├── environments
│ ├── environment.local.ts
│ ├── environment.prod.ts
│ └── environment.ts
├── index.html
├── main.ts
├── polyfills.ts
├── styles.scss
├── styles
│ ├── _theme-variables-collection.scss
│ ├── _themes.scss
│ ├── base
│ │ ├── _dark-variables.scss
│ │ ├── _fonts.scss
│ │ ├── _light-variables.scss
│ │ ├── _type.scss
│ │ └── _variables.scss
│ ├── components.styles.scss
│ ├── config
│ │ └── _include-media-config.scss
│ ├── layouts
│ │ ├── _footer.scss
│ │ ├── _global.scss
│ │ ├── _header.scss
│ │ └── _utilities.scss
│ ├── material-theme.scss
│ ├── mixins
│ │ └── _utilities.scss
│ ├── modules
│ │ ├── _blocks.scss
│ │ ├── _hero.scss
│ │ ├── _lists.scss
│ │ ├── _menu.scss
│ │ ├── _preloader.scss
│ │ ├── bootstrap-overrides
│ │ │ ├── _alert.scss
│ │ │ ├── _button.scss
│ │ │ ├── _dropdown.scss
│ │ │ ├── _form.scss
│ │ │ ├── _modal.scss
│ │ │ ├── _overrides.scss
│ │ │ └── _tooltips.scss
│ │ ├── cards
│ │ │ ├── _cards.scss
│ │ │ ├── _package.scss
│ │ │ ├── _post.scss
│ │ │ ├── _single-post.scss
│ │ │ └── _square.scss
│ │ ├── comments
│ │ │ └── _comments.scss
│ │ ├── mail-composer
│ │ │ └── _mail-composer.scss
│ │ └── utilities
│ │ │ ├── _form-fields.scss
│ │ │ └── _utilities.scss
│ ├── pages
│ │ └── user-actions
│ │ │ └── _form-pages.scss
│ └── vendors
│ │ ├── bootstrap
│ │ ├── .scss-lint.yml
│ │ ├── _alert.scss
│ │ ├── _badge.scss
│ │ ├── _breadcrumb.scss
│ │ ├── _button-group.scss
│ │ ├── _buttons.scss
│ │ ├── _card.scss
│ │ ├── _carousel.scss
│ │ ├── _close.scss
│ │ ├── _code.scss
│ │ ├── _ctemplar-bootstrap.scss
│ │ ├── _custom-forms.scss
│ │ ├── _custom.scss
│ │ ├── _dropdown.scss
│ │ ├── _forms.scss
│ │ ├── _grid.scss
│ │ ├── _images.scss
│ │ ├── _input-group.scss
│ │ ├── _jumbotron.scss
│ │ ├── _list-group.scss
│ │ ├── _media.scss
│ │ ├── _mixins.scss
│ │ ├── _modal.scss
│ │ ├── _nav.scss
│ │ ├── _navbar.scss
│ │ ├── _normalize.scss
│ │ ├── _pagination.scss
│ │ ├── _popover.scss
│ │ ├── _print.scss
│ │ ├── _progress.scss
│ │ ├── _reboot.scss
│ │ ├── _responsive-embed.scss
│ │ ├── _tables.scss
│ │ ├── _tooltip.scss
│ │ ├── _transitions.scss
│ │ ├── _type.scss
│ │ ├── _utilities.scss
│ │ ├── _variables.scss
│ │ ├── mixins
│ │ │ ├── _alert.scss
│ │ │ ├── _background-variant.scss
│ │ │ ├── _badge.scss
│ │ │ ├── _border-radius.scss
│ │ │ ├── _breakpoints.scss
│ │ │ ├── _buttons.scss
│ │ │ ├── _cards.scss
│ │ │ ├── _clearfix.scss
│ │ │ ├── _float.scss
│ │ │ ├── _forms.scss
│ │ │ ├── _gradients.scss
│ │ │ ├── _grid-framework.scss
│ │ │ ├── _grid.scss
│ │ │ ├── _hover.scss
│ │ │ ├── _image.scss
│ │ │ ├── _list-group.scss
│ │ │ ├── _lists.scss
│ │ │ ├── _nav-divider.scss
│ │ │ ├── _navbar-align.scss
│ │ │ ├── _pagination.scss
│ │ │ ├── _reset-text.scss
│ │ │ ├── _resize.scss
│ │ │ ├── _screen-reader.scss
│ │ │ ├── _size.scss
│ │ │ ├── _table-row.scss
│ │ │ ├── _text-emphasis.scss
│ │ │ ├── _text-hide.scss
│ │ │ ├── _text-truncate.scss
│ │ │ ├── _transforms.scss
│ │ │ └── _visibility.scss
│ │ └── utilities
│ │ │ ├── _align.scss
│ │ │ ├── _background.scss
│ │ │ ├── _borders.scss
│ │ │ ├── _clearfix.scss
│ │ │ ├── _display.scss
│ │ │ ├── _flex.scss
│ │ │ ├── _float.scss
│ │ │ ├── _position.scss
│ │ │ ├── _screenreaders.scss
│ │ │ ├── _sizing.scss
│ │ │ ├── _spacing.scss
│ │ │ ├── _text.scss
│ │ │ └── _visibility.scss
│ │ ├── ceaser
│ │ ├── _ceaser-easing.sass
│ │ └── ceaser-easing
│ │ │ ├── _ceaser.sass
│ │ │ ├── _ease-types.sass
│ │ │ ├── _easing-functions.sass
│ │ │ └── _easing-vars.sass
│ │ ├── ctemplar-fonts
│ │ ├── autocrypt.scss
│ │ └── fonts.scss
│ │ ├── fontawesome
│ │ ├── _animated.scss
│ │ ├── _bordered-pulled.scss
│ │ ├── _core.scss
│ │ ├── _fixed-width.scss
│ │ ├── _fontawesome.scss
│ │ ├── _icons.scss
│ │ ├── _larger.scss
│ │ ├── _list.scss
│ │ ├── _mixins.scss
│ │ ├── _rotated-flipped.scss
│ │ ├── _screen-reader.scss
│ │ ├── _stacked.scss
│ │ └── _variables.scss
│ │ ├── icomoon
│ │ └── _icomoon.scss
│ │ └── include-media
│ │ └── _include-media.scss
├── test.ts
├── tsconfig.app.json
├── tsconfig.spec.json
└── typings.d.ts
├── tsconfig.json
└── webpack.config.js
/.deepsource.toml:
--------------------------------------------------------------------------------
1 | version = 1
2 |
3 | test_patterns = ["test/**"]
4 |
5 | exclude_patterns = ["dist/**"]
6 |
7 | [[analyzers]]
8 | name = "javascript"
9 | enabled = true
10 |
11 | [analyzers.meta]
12 | environment = [
13 | "nodejs",
14 | "browser"
15 | ]
16 | plugins = ["angular"]
17 |
18 | [[transformers]]
19 | name = "prettier"
20 | enabled = true
21 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | # See https://eslint.org/docs/user-guide/configuring#eslintignore for more about ignoring files.
2 |
3 | # misc
4 | src/environments/
5 |
6 | # configuration
7 | electron-main.ts
8 | karma.conf.js
9 | webpack.config.js
10 | typings.d.ts
11 | test.ts
12 | protractor.conf.js
13 | patch-webpack.js
14 | electron-main.js
15 | package.json
16 |
17 | # spec
18 | **/*.spec.ts
19 |
20 | # dependencies
21 | node-modules/
22 |
23 | # build
24 | .DS_Store
25 | release/
26 | dist/
27 |
28 | # others
29 | docs/
30 | e2e/
31 | .github/
32 | README.md
33 |
34 | # assets
35 | src/assets/
36 | src/styles/
37 | src/assets/js/ckeditor-build/ckeditor.js
38 | src/assets/js/ckeditor-build/ckeditor.js.map
39 |
40 | # others
41 | npm-debug.log*
42 | npm-debug.log*
43 | npm-error.log*
44 |
45 | # test
46 | *.spec.ts
47 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Report here if you found something isn't working as expected.
4 | title: ''
5 | labels: 'bug'
6 | assignees: ''
7 | ---
8 |
9 | ### Your environment
10 |
11 | Include, at least, your web browser version and the operative system.
12 |
13 | ### Picture, video or steps to reproduce
14 |
15 | 1. Tell us how to reproduce this issue, step by step.
16 | 2. You can include media content like images or videos.
17 |
18 | ### Explanation
19 |
20 | Tell us any extra details.
21 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest here if you have any new feature or improvement request.
4 | title: ''
5 | labels: 'enhacement'
6 | assignees: ''
7 | ---
8 |
9 | ### Expected behavior
10 |
11 | Tell us what should happen.
12 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | Fixes task (link or #num):
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | /.idea
3 | /.vscode
4 | /dist
5 | /e2e/*.js
6 | /e2e/*.map
7 | /release
8 | /tmp/
9 | electron-main.js*
10 | node_modules
11 | src/assets/fonts/icomoon/libs/icomoon.zip
12 | Thumbs.db
13 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "src/assets/theme"]
2 | path = src/assets/theme
3 | url = https://github.com/CTemplar/webclient-themes.git
--------------------------------------------------------------------------------
/.husky/.gitignore:
--------------------------------------------------------------------------------
1 | _
2 |
--------------------------------------------------------------------------------
/.husky/pre-commit:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 | . "$(dirname "$0")/_/husky.sh"
3 |
4 | ./node_modules/.bin/lint-staged
5 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | # Ignore Javascript Files
2 | src/assets/static/pgp-worker.js
3 | src/assets/js/ckeditor-build/ckeditor.js
4 | src/assets/js/ckeditor-build/ckeditor.js.map
5 | package-lock.json
6 | yarn.lock
7 | node_modules
8 | node_modules/*
9 | e2e/*
10 | dist/*
11 |
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "arrowParens": "avoid",
3 | "printWidth": 120,
4 | "semi": true,
5 | "singleQuote": true,
6 | "trailingComma": "all",
7 | "endOfLine": "auto"
8 | }
9 |
--------------------------------------------------------------------------------
/docs/images/calculate-hash-offline-github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-offline-github.png
--------------------------------------------------------------------------------
/docs/images/calculate-hash-offline.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-offline.png
--------------------------------------------------------------------------------
/docs/images/calculate-hash-online-1.1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-online-1.1.png
--------------------------------------------------------------------------------
/docs/images/calculate-hash-online-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-online-1.png
--------------------------------------------------------------------------------
/docs/images/calculate-hash-online-2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-online-2.png
--------------------------------------------------------------------------------
/docs/images/calculate-hash-online-github.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-online-github.png
--------------------------------------------------------------------------------
/docs/images/calculate-hash-online-github1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-online-github1.png
--------------------------------------------------------------------------------
/docs/images/calculate-hash-online-github2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/calculate-hash-online-github2.png
--------------------------------------------------------------------------------
/docs/images/electron-index-html-diff.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/electron-index-html-diff.png
--------------------------------------------------------------------------------
/docs/images/hash-online-raw-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/hash-online-raw-1.png
--------------------------------------------------------------------------------
/docs/images/right-click.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/right-click.png
--------------------------------------------------------------------------------
/docs/images/save-as-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/save-as-file.png
--------------------------------------------------------------------------------
/docs/images/save-as-html-only-file.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/save-as-html-only-file.png
--------------------------------------------------------------------------------
/docs/images/save-github-file1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/docs/images/save-github-file1.png
--------------------------------------------------------------------------------
/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 |
3 | describe('frontend App', () => {
4 | let page: AppPage;
5 |
6 | beforeEach(() => {
7 | page = new AppPage();
8 | });
9 |
10 | it('should display welcome message', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('Welcome to app!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/e2e",
5 | "module": "commonjs",
6 | "types": ["mocha"]
7 | },
8 | "include": ["**/*.ts"]
9 | }
10 |
--------------------------------------------------------------------------------
/electron-builder.json:
--------------------------------------------------------------------------------
1 | {
2 | "productName": "CTemplar",
3 | "appId": "com.github.ctemplar.webclient",
4 | "directories": {
5 | "output": "release/"
6 | },
7 | "publish": [
8 | {
9 | "provider": "github",
10 | "owner": "ctemplar",
11 | "repo": "webclient"
12 | }
13 | ],
14 | "win": {
15 | "icon": "dist/assets/icons/icon.png",
16 | "target": ["portable"]
17 | },
18 | "mac": {
19 | "icon": "dist/assets/icons/icon@512.png",
20 | "category": "public.app-category.social-networking",
21 | "target": ["dmg"]
22 | },
23 | "linux": {
24 | "icon": "dist/assets/icons/icon.png",
25 | "category": "Network",
26 | "target": ["AppImage"]
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/electron-tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "sourceMap": true,
4 | "declaration": false,
5 | "moduleResolution": "node",
6 | "emitDecoratorMetadata": true,
7 | "experimentalDecorators": true,
8 | "target": "es5",
9 | "types": ["node"],
10 | "lib": ["es2017", "es2016", "es2015", "dom"]
11 | },
12 | "files": ["electron-main.ts"],
13 | "exclude": ["node_modules", "**/*.spec.ts"]
14 | }
15 |
--------------------------------------------------------------------------------
/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/config/configuration-file.html
3 |
4 | module.exports = function (config) {
5 | config.set({
6 | basePath: '',
7 | frameworks: ['jasmine', '@angular-devkit/build-angular'],
8 | plugins: [
9 | require('karma-jasmine'),
10 | require('karma-chrome-launcher'),
11 | require('karma-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular-devkit/build-angular/plugins/karma'),
14 | ],
15 | client: {
16 | clearContext: false, // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | dir: require('path').join(__dirname, 'coverage'),
20 | reports: ['html', 'lcovonly'],
21 | fixWebpackSourcePaths: true,
22 | },
23 |
24 | reporters: ['progress', 'kjhtml'],
25 | port: 9876,
26 | colors: true,
27 | logLevel: config.LOG_INFO,
28 | autoWatch: true,
29 | browsers: ['Chrome'],
30 | singleRun: false,
31 | });
32 | };
33 |
--------------------------------------------------------------------------------
/patch-webpack.js:
--------------------------------------------------------------------------------
1 | const f = 'node_modules/@angular-devkit/build-angular/src/angular-cli-files/models/webpack-configs/browser.js';
2 | const fs = require('fs');
3 |
4 | fs.readFile(f, 'utf8', function (err, data) {
5 | if (err) {
6 | return console.log(err);
7 | }
8 | let result = data.replace(
9 | /node: false/g,
10 | "node: {crypto: true, stream: true, dns: 'empty', net: 'empty', fs: 'empty', tls: 'empty'}",
11 | );
12 |
13 | fs.writeFile(f, result, 'utf8', function (error) {
14 | if (error) return console.log(error);
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: ['./e2e/**/*.e2e-spec.ts'],
9 | capabilities: {
10 | browserName: 'chrome',
11 | },
12 | directConnect: true,
13 | baseUrl: 'http://localhost:4200/',
14 | framework: 'jasmine',
15 | jasmineNodeOpts: {
16 | showColors: true,
17 | defaultTimeoutInterval: 30000,
18 | print: function () {},
19 | },
20 | onPrepare() {
21 | require('ts-node').register({
22 | project: 'e2e/tsconfig.e2e.json',
23 | });
24 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
25 | },
26 | };
27 |
--------------------------------------------------------------------------------
/src/CNAME:
--------------------------------------------------------------------------------
1 | gh.ctemplar.com
--------------------------------------------------------------------------------
/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | Cookies are required to use CTemplar. Please enable them in your browser.
19 | Learn more.
20 |
21 |
--------------------------------------------------------------------------------
/src/app/app.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/app.component.scss
--------------------------------------------------------------------------------
/src/app/app.error-handler.ts:
--------------------------------------------------------------------------------
1 | import { ErrorHandler, Injectable } from '@angular/core';
2 | import * as Sentry from '@sentry/browser';
3 |
4 | import { AppConfig } from '../environments/environment';
5 |
6 | @Injectable({
7 | providedIn: 'root',
8 | })
9 | export class SentryErrorHandler implements ErrorHandler {
10 | handleError(error: any) {
11 | Sentry.captureException(error.originalError || error);
12 | }
13 | }
14 |
15 | export function errorHandlerFactory() {
16 | if (AppConfig.production) {
17 | return new SentryErrorHandler();
18 | }
19 | return new ErrorHandler();
20 | }
21 |
--------------------------------------------------------------------------------
/src/app/footer/footer.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { FooterComponent } from './footer.component';
4 |
5 | describe('FooterComponent', () => {
6 | let component: FooterComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [FooterComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(FooterComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/footer/footer.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { PRIMARY_WEBSITE } from '../shared/config';
4 |
5 | @Component({
6 | selector: 'app-footer',
7 | templateUrl: './footer.component.html',
8 | styleUrls: ['./footer.component.scss'],
9 | })
10 | export class FooterComponent {
11 | primaryWebsite = PRIMARY_WEBSITE;
12 | }
13 |
--------------------------------------------------------------------------------
/src/app/footer/footer.module.spec.ts:
--------------------------------------------------------------------------------
1 | import { FooterModule } from './footer.module';
2 |
3 | describe('FooterModule', () => {
4 | let footerModule: FooterModule;
5 |
6 | beforeEach(() => {
7 | footerModule = new FooterModule();
8 | });
9 |
10 | it('should create an instance', () => {
11 | expect(footerModule).toBeTruthy();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/src/app/footer/footer.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { NgModule } from '@angular/core';
3 | import { RouterModule } from '@angular/router';
4 | import { TranslateModule } from '@ngx-translate/core';
5 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
6 |
7 | import { FooterComponent } from './footer.component';
8 |
9 | @NgModule({
10 | declarations: [FooterComponent],
11 | imports: [CommonModule, NgbModule, RouterModule, TranslateModule],
12 | exports: [FooterComponent],
13 | })
14 | export class FooterModule {}
15 |
--------------------------------------------------------------------------------
/src/app/header/header.component.scss:
--------------------------------------------------------------------------------
1 | .language-dropdown {
2 | text-align: left;
3 | padding: 0.5rem 0.5rem 0.5rem 1rem;
4 | }
5 |
--------------------------------------------------------------------------------
/src/app/header/header.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { HeaderComponent } from './header.component';
4 |
5 | describe('HeaderComponent', () => {
6 | let component: HeaderComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [HeaderComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(HeaderComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/header/header.module.spec.ts:
--------------------------------------------------------------------------------
1 | import { HeaderModule } from './header.module';
2 |
3 | describe('HeaderModule', () => {
4 | let headerModule: HeaderModule;
5 |
6 | beforeEach(() => {
7 | headerModule = new HeaderModule();
8 | });
9 |
10 | it('should create an instance', () => {
11 | expect(headerModule).toBeTruthy();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/src/app/header/header.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { NgModule } from '@angular/core';
3 | import { RouterModule } from '@angular/router';
4 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
5 |
6 | import { SharedModule } from '../shared/shared.module';
7 |
8 | import { HeaderComponent } from './header.component';
9 |
10 | @NgModule({
11 | declarations: [HeaderComponent],
12 | imports: [CommonModule, NgbModule, RouterModule, SharedModule],
13 | exports: [HeaderComponent],
14 | })
15 | export class HeaderModule {}
16 |
--------------------------------------------------------------------------------
/src/app/mail/dialogs/export-message/export-message.component.html:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/mail/dialogs/export-message/export-message.component.html
--------------------------------------------------------------------------------
/src/app/mail/dialogs/export-message/export-message.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/mail/dialogs/export-message/export-message.component.scss
--------------------------------------------------------------------------------
/src/app/mail/dialogs/export-message/export-message.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ExportMessageComponent } from './export-message.component';
4 |
5 | describe('ExportMessageComponent', () => {
6 | let component: ExportMessageComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [ExportMessageComponent],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(ExportMessageComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/app/mail/dialogs/export-message/export-message.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-export-message',
5 | templateUrl: './export-message.component.html',
6 | styleUrls: ['./export-message.component.scss'],
7 | })
8 | export class ExportMessageComponent implements OnInit {
9 | constructor() {}
10 |
11 | ngOnInit(): void {}
12 | }
13 |
--------------------------------------------------------------------------------
/src/app/mail/dialogs/import-private-key/import-private-key.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../../styles/vendors/include-media/include-media';
2 | @import '../../../../styles/config/include-media-config';
3 |
4 | .dropdown.dropdown-sm {
5 | .dropdown-toggle {
6 | padding-right: 0.75rem;
7 | padding-left: 0.75rem;
8 | border-radius: 2px;
9 | font-size: 14px;
10 | height: 2rem;
11 | width: 100%;
12 | line-height: 1;
13 |
14 | &::before {
15 | right: 0.75rem;
16 | }
17 |
18 | .form-content-holder & {
19 | @include media('<=sm') {
20 | font-size: 0.875rem;
21 | height: 2.625rem;
22 | }
23 | }
24 | }
25 |
26 | .dropdown-item {
27 | line-height: 1;
28 |
29 | @include media('<=sm') {
30 | font-size: 0.875rem;
31 | }
32 | }
33 | }
34 |
35 | .field-title {
36 | font-size: 14px;
37 | }
38 |
--------------------------------------------------------------------------------
/src/app/mail/dialogs/import-private-key/import-private-key.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { ImportPrivateKeyComponent } from './import-private-key.component';
4 |
5 | describe('ImportPrivateKeyComponent', () => {
6 | let component: ImportPrivateKeyComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ImportPrivateKeyComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(ImportPrivateKeyComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/dialogs/payment-failure-notice/payment-failure-notice.component.html:
--------------------------------------------------------------------------------
1 |
6 |
7 |
{{ 'mail_dialogs.payment_message' | translate }}
8 |
9 |
14 |
--------------------------------------------------------------------------------
/src/app/mail/dialogs/payment-failure-notice/payment-failure-notice.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap';
4 |
5 | @Component({
6 | selector: 'app-payment-failure-notice',
7 | templateUrl: './payment-failure-notice.component.html',
8 | changeDetection: ChangeDetectionStrategy.OnPush,
9 | })
10 | export class PaymentFailureNoticeComponent {
11 | constructor(private activeModal: NgbActiveModal, private router: Router) {}
12 |
13 | updatePayment() {
14 | this.router.navigateByUrl('/mail/settings/dashboard-and-plans');
15 | this.activeModal.close();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/mail/mail-contact/mail-contact.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailContactComponent } from './mail-contact.component';
4 |
5 | describe('MailContactComponent', () => {
6 | let component: MailContactComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailContactComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailContactComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-contact/save-contact/save-contact.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { SaveContactComponent } from './save-contact.component';
4 |
5 | describe('SaveContactComponent', () => {
6 | let component: SaveContactComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [SaveContactComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(SaveContactComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-body/mail-detail-body.component.scss:
--------------------------------------------------------------------------------
1 | .mail-content {
2 | position: relative;
3 |
4 | .msg-reply-dropdown {
5 | position: absolute;
6 | right: 20px;
7 | }
8 | }
9 | .attachment-content {
10 | padding-left: 25px;
11 | }
12 |
13 | .msg-reply-content {
14 | overflow: auto;
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-body/mail-detail-body.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailDetailBodyComponent } from './mail-detail-body.component';
4 |
5 | describe('MailDetailBodyComponent', () => {
6 | let component: MailDetailBodyComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailDetailBodyComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailDetailBodyComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-decryption-error/mail-detail-decryption-error.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ 'mail_detail.error' | translate }}:
4 | {{ 'mail_detail.unable_decrypt_message' | translate }}
5 |
6 |
7 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-decryption-error/mail-detail-decryption-error.component.scss:
--------------------------------------------------------------------------------
1 | .message-error {
2 | margin: 5px 0;
3 | padding: 5px;
4 | background: #e74c3c;
5 | color: white;
6 | border-radius: 3px;
7 | box-shadow: inset 0 0 0 2px #dadce0;
8 | .error-title {
9 | font-weight: bold;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-decryption-error/mail-detail-decryption-error.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailDetailDecryptionErrorComponent } from './mail-detail-decryption-error.component';
4 |
5 | describe('MailDetailDecryptionErrorComponent', () => {
6 | let component: MailDetailDecryptionErrorComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailDetailDecryptionErrorComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailDetailDecryptionErrorComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-decryption-error/mail-detail-decryption-error.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-mail-detail-decryption-error',
5 | templateUrl: './mail-detail-decryption-error.component.html',
6 | styleUrls: ['./mail-detail-decryption-error.component.scss'],
7 | })
8 | export class MailDetailDecryptionErrorComponent implements OnInit {
9 | ngOnInit(): void {}
10 | }
11 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-encryption-type-icon/mail-detail-encryption-type-icon.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-encryption-type-icon/mail-detail-encryption-type-icon.component.scss:
--------------------------------------------------------------------------------
1 | i {
2 | margin-left: 5px;
3 | font-size: 13px;
4 | }
5 |
6 | .has-last-action {
7 | margin-left: 22px;
8 | }
9 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-encryption-type-icon/mail-detail-encryption-type-icon.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailDetailEncryptionTypeIconComponent } from './mail-detail-encryption-type-icon.component';
4 |
5 | describe('MailDetailEncryptionTypeIconComponent', () => {
6 | let component: MailDetailEncryptionTypeIconComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailDetailEncryptionTypeIconComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailDetailEncryptionTypeIconComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-encryption-type-icon/mail-detail-encryption-type-icon.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, OnInit } from '@angular/core';
2 |
3 | import { Mail } from '../../../store/models';
4 | import { EncryptionType } from '../../../store/datatypes';
5 |
6 | @Component({
7 | selector: 'app-mail-detail-encryption-type-icon',
8 | templateUrl: './mail-detail-encryption-type-icon.component.html',
9 | styleUrls: ['./mail-detail-encryption-type-icon.component.scss'],
10 | })
11 | export class MailDetailEncryptionTypeIconComponent implements OnInit {
12 | @Input() mail: Mail;
13 |
14 | encryptionType?: EncryptionType;
15 |
16 | lastAction?: string;
17 |
18 | // eslint-disable-next-line class-methods-use-this
19 | ngOnInit(): void {
20 | if (this.mail) {
21 | this.lastAction = this.mail.last_action;
22 | if (this.mail.encryption && this.mail.encryption.password_hint) {
23 | this.encryptionType = EncryptionType.PGP_PASSWORD;
24 | } else if (this.mail.encryption_type) {
25 | this.encryptionType = EncryptionType.PGP_MIME_INLINE;
26 | } else {
27 | this.encryptionType = EncryptionType.PGP_END_TO_END;
28 | }
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-header/mail-detail-header.component.scss:
--------------------------------------------------------------------------------
1 | .expand-collapse {
2 | margin-top: 1px;
3 | }
4 |
5 | .folder-batch {
6 | background: #4d5f71;
7 | color: white;
8 | padding: 0 6px;
9 | border-radius: 2px;
10 | height: 20px;
11 | line-height: 18px;
12 | min-width: 55px;
13 | text-align: center;
14 | overflow: hidden;
15 | max-width: 10rem;
16 | text-overflow: ellipsis;
17 | font-size: 14px;
18 | white-space: nowrap;
19 | margin-right: 26px;
20 | }
21 |
22 | .mail-header {
23 | border: solid 1px #e5e5e5;
24 | margin: 5px;
25 | padding: 5px 1rem;
26 | }
27 |
28 | .unsubscribe {
29 | margin-left: 10px;
30 | font-weight: 100;
31 | font-size: small;
32 | }
33 |
34 | .verified-sender {
35 | color: green;
36 | margin-left: 5px;
37 | margin-right: 5px;
38 | }
39 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-header/mail-detail-header.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailDetailHeaderComponent } from './mail-detail-header.component';
4 |
5 | describe('MailDetailHeaderComponent', () => {
6 | let component: MailDetailHeaderComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailDetailHeaderComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailDetailHeaderComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-password-decryption-panel/mail-detail-password-decryption-panel.component.scss:
--------------------------------------------------------------------------------
1 | .decrypt-password-form-container {
2 | margin-bottom: 20px;
3 | .decrypt-password-form {
4 | display: flex;
5 | width: 55%;
6 | .decrypt-password-element {
7 | height: 40px;
8 | padding: 3px 0;
9 | button {
10 | color: var(--text-muted);
11 | }
12 | }
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail-password-decryption-panel/mail-detail-password-decryption-panel.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailDetailPasswordDecryptionPanelComponent } from './mail-detail-password-decryption-panel.component';
4 |
5 | describe('MailDetailPasswordDecryptionPanelComponent', () => {
6 | let component: MailDetailPasswordDecryptionPanelComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailDetailPasswordDecryptionPanelComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailDetailPasswordDecryptionPanelComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-detail/mail-detail.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailDetailComponent } from './mail-detail.component';
4 |
5 | describe('MailDetailComponent', () => {
6 | let component: MailDetailComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailDetailComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailDetailComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-footer/mail-footer.component.html:
--------------------------------------------------------------------------------
1 |
2 |
18 |
--------------------------------------------------------------------------------
/src/app/mail/mail-footer/mail-footer.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailFooterComponent } from './mail-footer.component';
4 |
5 | describe('MailFooterComponent', () => {
6 | let component: MailFooterComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailFooterComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailFooterComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-footer/mail-footer.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Store } from '@ngrx/store';
3 | import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
4 |
5 | import { AppState, UserState } from '../../store/datatypes';
6 | import { PRIMARY_WEBSITE } from '../../shared/config';
7 |
8 | @UntilDestroy()
9 | @Component({
10 | selector: 'app-mail-footer',
11 | templateUrl: './mail-footer.component.html',
12 | styleUrls: ['./mail-footer.component.scss'],
13 | })
14 | export class MailFooterComponent implements OnInit {
15 | public userState: UserState;
16 |
17 | primaryWebsite = PRIMARY_WEBSITE;
18 |
19 | constructor(private store: Store) {}
20 |
21 | ngOnInit() {
22 | this.store
23 | .select(state => state.user)
24 | .pipe(untilDestroyed(this))
25 | .subscribe((user: UserState) => {
26 | this.userState = user;
27 | });
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/app/mail/mail-header/mail-header.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailHeaderComponent } from './mail-header.component';
4 |
5 | describe('MailHeaderComponent', () => {
6 | let component: MailHeaderComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailHeaderComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailHeaderComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-list/mail-folder/generic-folder/generic-folder.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { GenericFolderComponent } from './generic-folder.component';
4 |
5 | describe('GenericFolderComponent', () => {
6 | let component: GenericFolderComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [GenericFolderComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(GenericFolderComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-list/mail-list.component.scss:
--------------------------------------------------------------------------------
1 | @import '../../../styles/base/variables';
2 | @import '../../../styles/vendors/include-media/include-media';
3 | @import '../../../styles/config/include-media-config';
4 | @import '../../../styles/vendors/ceaser/ceaser-easing';
5 |
6 | // == More list options
7 | #moreOptionsDropdownMenuButton {
8 | width: 5.5rem;
9 | }
10 |
11 | #moreOptionsDropdownMenu {
12 | width: 220px;
13 | }
14 |
--------------------------------------------------------------------------------
/src/app/mail/mail-list/mail-list.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailListComponent } from './mail-list.component';
4 |
5 | describe('MailListComponent', () => {
6 | let component: MailListComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailListComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailListComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/addresses-signature/addresses-signature.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { AddressesSignatureComponent } from './addresses-signature.component';
4 |
5 | describe('AddressesSignatureComponent', () => {
6 | let component: AddressesSignatureComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [AddressesSignatureComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(AddressesSignatureComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/custom-domains/custom-domains.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { CustomDomainsComponent } from './custom-domains.component';
4 |
5 | describe('CustomDomainsComponent', () => {
6 | let component: CustomDomainsComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [CustomDomainsComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(CustomDomainsComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/folders/folders.component.scss:
--------------------------------------------------------------------------------
1 | @import '~styles/base/variables';
2 |
3 | .folder-item {
4 | .show-ellipses {
5 | display: flex;
6 | align-items: center;
7 | }
8 |
9 | .folder-color-box {
10 | height: 1rem;
11 | width: 1rem;
12 | }
13 |
14 | .folder-name {
15 | vertical-align: sub;
16 | }
17 | }
18 |
19 | .folders-list {
20 | height: auto;
21 | border-top: 1px solid var(--dropdown-border-color);
22 | border-bottom: 1px solid var(--dropdown-border-color);
23 | }
24 |
25 | .sort-alphabetic-btn {
26 | color: rgba(0, 0, 0, 0.38);
27 | min-width: 40px;
28 | margin: 0 10px;
29 | }
30 |
31 | .folder-drag-handle {
32 | cursor: move;
33 | }
34 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/folders/folders.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { FoldersComponent } from './folders.component';
4 |
5 | describe('FoldersComponent', () => {
6 | let component: FoldersComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [FoldersComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(FoldersComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/invite-codes/invite-codes.component.scss:
--------------------------------------------------------------------------------
1 | .ui-header-subtitle {
2 | display: inline-block;
3 | }
4 |
5 | .copy-btn {
6 | color: #616161 !important;
7 | }
8 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/invite-codes/invite-codes.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { InviteCodesComponent } from './invite-codes.component';
4 |
5 | describe('InviteCodesComponent', () => {
6 | let component: InviteCodesComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [InviteCodesComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(InviteCodesComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/mail-autoresponder/mail-autoresponder.component.scss:
--------------------------------------------------------------------------------
1 | ::ng-deep .ql-editor.ql-blank::before {
2 | color: var(--input-color-placeholder);
3 | }
4 |
5 | .col-row {
6 | padding-left: 15px;
7 | padding-right: 15px;
8 | }
9 |
10 | ::ng-deep .mat-checkbox .mat-checkbox-frame {
11 | border: 2px solid var(--mat-checkbox-border-color);
12 | }
13 |
14 | ::ng-deep .mat-checkbox .mat-checkbox-background {
15 | border: var(--width-0-2) solid var(--mat-checkbox-border-color);
16 | }
17 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/mail-forwarding/mail-forwarding.component.scss:
--------------------------------------------------------------------------------
1 | .mat-row {
2 | padding-left: 2px;
3 | }
4 |
5 | ::ng-deep .mat-checkbox .mat-checkbox-frame {
6 | border: 2px solid var(--mat-checkbox-border-color);
7 | }
8 |
9 | ::ng-deep .mat-checkbox .mat-checkbox-background {
10 | border: var(--width-0-2) solid var(--mat-checkbox-border-color);
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/mail-settings.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailSettingsComponent } from './mail-settings.component';
4 |
5 | describe('MailSettingsComponent', () => {
6 | let component: MailSettingsComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailSettingsComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailSettingsComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/organization/organization-dashboard/organization-dashboard.component.scss:
--------------------------------------------------------------------------------
1 | @import '~styles/base/variables';
2 | @import '~styles/vendors/include-media/include-media';
3 | @import '~styles/config/include-media-config';
4 | @import '~styles/vendors/ceaser/ceaser-easing';
5 | @import '~styles/theme-variables-collection';
6 | @import '~styles/themes';
7 |
8 | .loading-spinner {
9 | position: fixed;
10 | top: 50%;
11 | left: 50%;
12 | }
13 |
14 | .text-color-danger {
15 | color: var(--text-danger);
16 | }
17 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/organization/organization-dashboard/organization-dashboard.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { By } from '@angular/platform-browser';
4 | import { DebugElement } from '@angular/core';
5 |
6 | import { OrganizationDashboardComponent } from './organization-dashboard.component';
7 |
8 | describe('OrganizationDashboardComponent', () => {
9 | let component: OrganizationDashboardComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [OrganizationDashboardComponent],
15 | }).compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(OrganizationDashboardComponent);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/organization/organization-editor/organization-editor.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { By } from '@angular/platform-browser';
4 | import { DebugElement } from '@angular/core';
5 |
6 | import { OrganizationEditorComponent } from './organization-editor.component';
7 |
8 | describe('OrganizationEditorComponent', () => {
9 | let component: OrganizationEditorComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [OrganizationEditorComponent],
15 | }).compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(OrganizationEditorComponent);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/organization/organization-users-list/organization-users-list.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { By } from '@angular/platform-browser';
4 | import { DebugElement } from '@angular/core';
5 |
6 | import { OrganizationUsersListComponent } from './organization-users-list.component';
7 |
8 | describe('OrganizationUsersListComponent', () => {
9 | let component: OrganizationUsersListComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [OrganizationUsersListComponent],
15 | }).compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(OrganizationUsersListComponent);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/organization/organization-users/organization-users.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { OrganizationUsersComponent } from './organization-users.component';
4 |
5 | describe('OrganizationUsersComponent', () => {
6 | let component: OrganizationUsersComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [OrganizationUsersComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(OrganizationUsersComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/organization/organization-viewer/organization-viewer.component.scss:
--------------------------------------------------------------------------------
1 | .text-color-danger {
2 | color: var(--text-danger);
3 | }
4 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/organization/organization-viewer/organization-viewer.component.spec.ts:
--------------------------------------------------------------------------------
1 | /* tslint:disable:no-unused-variable */
2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3 | import { By } from '@angular/platform-browser';
4 | import { DebugElement } from '@angular/core';
5 |
6 | import { OrganizationViewerComponent } from './organization-viewer.component';
7 |
8 | describe('OrganizationViewerComponent', () => {
9 | let component: OrganizationViewerComponent;
10 | let fixture: ComponentFixture;
11 |
12 | beforeEach(async(() => {
13 | TestBed.configureTestingModule({
14 | declarations: [OrganizationViewerComponent],
15 | }).compileComponents();
16 | }));
17 |
18 | beforeEach(() => {
19 | fixture = TestBed.createComponent(OrganizationViewerComponent);
20 | component = fixture.componentInstance;
21 | fixture.detectChanges();
22 | });
23 |
24 | it('should create', () => {
25 | expect(component).toBeTruthy();
26 | });
27 | });
28 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/save-list-contact/save-list-contact.component.scss:
--------------------------------------------------------------------------------
1 | div.disabled {
2 | pointer-events: none;
3 | opacity: 0.4;
4 | }
5 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/save-list-contact/save-list-contact.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { SaveListContactComponent } from './save-list-contact.component';
4 |
5 | describe('SaveListContactComponent', () => {
6 | let component: SaveListContactComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [SaveListContactComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(SaveListContactComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/security/security.component.scss:
--------------------------------------------------------------------------------
1 | .password-content-holder {
2 | max-width: 416px;
3 | }
4 |
5 | .notice {
6 | color: red;
7 | }
8 |
9 | .subject-encryption.disabled {
10 | pointer-events: none;
11 | cursor: not-allowed;
12 |
13 | label {
14 | color: rgba(0, 0, 0, 0.38) !important;
15 | }
16 |
17 | input[type='radio'].fancy-field-control:checked + label::after {
18 | background: rgba(0, 0, 0, 0.38) !important;
19 | }
20 |
21 | input[type='radio'].fancy-field-control:checked + label::before {
22 | border-color: rgba(0, 0, 0, 0.38) !important;
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/app/mail/mail-settings/security/security.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { SecurityComponent } from './security.component';
4 |
5 | describe('SecurityComponent', () => {
6 | let component: SecurityComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [SecurityComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(SecurityComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-sidebar/compose-mail-dialog/compose-mail-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .border-lightgrey {
2 | border: 1px solid #e5e5e5 !important;
3 | }
4 |
--------------------------------------------------------------------------------
/src/app/mail/mail-sidebar/compose-mail/composer-encryption-type-icon/composer-encryption-type-icon.component.scss:
--------------------------------------------------------------------------------
1 | .pgp-mime-inline-icon {
2 | color: green;
3 | }
4 |
5 | .autocrypt-enabled-icon,
6 | .autocrypt-encrypt-discourage-icon {
7 | color: rgb(251, 140, 2);
8 | }
9 |
10 | .autocrypt-enabled-mutual-icon,
11 | .autocrypt-encrypt-icon {
12 | color: #005fa9;
13 | }
14 |
--------------------------------------------------------------------------------
/src/app/mail/mail-sidebar/compose-mail/composer-encryption-type-icon/composer-encryption-type-icon.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { ComposerEncryptionTypeIconComponent } from './composer-encryption-type-icon.component';
4 |
5 | describe('ComposerEncryptionTypeIconComponent', () => {
6 | let component: ComposerEncryptionTypeIconComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ComposerEncryptionTypeIconComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(ComposerEncryptionTypeIconComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-sidebar/compose-mail/receiver-email-chip/receiver-email-chip.component.scss:
--------------------------------------------------------------------------------
1 | .tag-chip-info {
2 | display: inline-block;
3 | }
4 |
5 | .tag-chip-info:hover {
6 | -webkit-transform: scale(1.1);
7 | -moz-transform: scale(1.1);
8 | -ms-transform: scale(1.1);
9 | -o-transform: scale(1.1);
10 | transform: scale(1.1);
11 | transform-origin: center center;
12 | }
13 |
--------------------------------------------------------------------------------
/src/app/mail/mail-sidebar/compose-mail/receiver-email-chip/receiver-email-chip.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { ReceiverEmailChipComponent } from './receiver-email-chip.component';
4 |
5 | describe('ReceiverEmailChipComponent', () => {
6 | let component: ReceiverEmailChipComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [ReceiverEmailChipComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(ReceiverEmailChipComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail-sidebar/mail-sidebar.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailSidebarComponent } from './mail-sidebar.component';
4 |
5 | describe('MailSidebarComponent', () => {
6 | let component: MailSidebarComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailSidebarComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailSidebarComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { MailComponent } from './mail.component';
4 |
5 | describe('MailComponent', () => {
6 | let component: MailComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [MailComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(MailComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/mail/mail.module.spec.ts:
--------------------------------------------------------------------------------
1 | import { MailModule } from './mail.module';
2 |
3 | describe('MailModule', () => {
4 | let mailModule: MailModule;
5 |
6 | beforeEach(() => {
7 | mailModule = new MailModule();
8 | });
9 |
10 | it('should create an instance', () => {
11 | expect(mailModule).toBeTruthy();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/src/app/pages/pages-donate/pages-donate.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/pages/pages-donate/pages-donate.component.scss
--------------------------------------------------------------------------------
/src/app/pages/pages-donate/pages-donate.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { PagesDonateComponent } from './pages-donate.component';
4 |
5 | describe('PagesDonateComponent', () => {
6 | let component: PagesDonateComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [PagesDonateComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(PagesDonateComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/pages/pages-donate/payment-options/payment-options.component.html:
--------------------------------------------------------------------------------
1 |
31 |
--------------------------------------------------------------------------------
/src/app/pages/pages-donate/payment-options/payment-options.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/pages/pages-donate/payment-options/payment-options.component.scss
--------------------------------------------------------------------------------
/src/app/pages/pages-donate/payment-options/payment-options.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { PaymentOptionsComponent } from './payment-options.component';
4 |
5 | describe('PaymentOptionsComponent', () => {
6 | let component: PaymentOptionsComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [PaymentOptionsComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(PaymentOptionsComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/pages/pages-donate/payment-options/payment-options.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, ChangeDetectionStrategy } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-payment-options',
5 | templateUrl: './payment-options.component.html',
6 | styleUrls: ['./payment-options.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class PaymentOptionsComponent {}
10 |
--------------------------------------------------------------------------------
/src/app/pages/pages-routing.module.ts:
--------------------------------------------------------------------------------
1 | import { NgModule } from '@angular/core';
2 | import { RouterModule, Routes } from '@angular/router';
3 |
4 | import { BitcoinFormComponent } from '../shared/components/bitcoin-form/bitcoin-form.component';
5 | import { PricingPlansComponent } from '../shared/components/pricing-plans/pricing-plans.component';
6 | import { StripeFormComponent } from '../shared/components/stripe-form/stripe-form.component';
7 |
8 | import { PagesDonateComponent } from './pages-donate/pages-donate.component';
9 | import { PaymentOptionsComponent } from './pages-donate/payment-options/payment-options.component';
10 |
11 | const routes: Routes = [
12 | {
13 | path: 'donate',
14 | component: PagesDonateComponent,
15 | children: [
16 | { path: '', component: PaymentOptionsComponent },
17 | { path: 'stripe', component: StripeFormComponent },
18 | { path: 'bitcoin', component: BitcoinFormComponent },
19 | ],
20 | },
21 | ];
22 |
23 | @NgModule({
24 | imports: [RouterModule.forChild(routes)],
25 | exports: [RouterModule],
26 | })
27 | export class PagesRoutingModule {}
28 |
--------------------------------------------------------------------------------
/src/app/pages/pages.module.ts:
--------------------------------------------------------------------------------
1 | import { CommonModule } from '@angular/common';
2 | import { NgModule } from '@angular/core';
3 | import { NgbModule } from '@ng-bootstrap/ng-bootstrap';
4 |
5 | import { SharedModule } from '../shared/shared.module';
6 |
7 | import { PagesDonateComponent } from './pages-donate/pages-donate.component';
8 | import { PaymentOptionsComponent } from './pages-donate/payment-options/payment-options.component';
9 | import { PagesRoutingModule } from './pages-routing.module';
10 |
11 | @NgModule({
12 | imports: [CommonModule, NgbModule, PagesRoutingModule, SharedModule],
13 | declarations: [PagesDonateComponent, PaymentOptionsComponent],
14 | })
15 | export class PagesModule {}
16 |
--------------------------------------------------------------------------------
/src/app/shared/circle-bar-spinner/circle-bar-spinner.component.scss:
--------------------------------------------------------------------------------
1 | .spinner-container {
2 | display: inline-block;
3 | svg {
4 | vertical-align: middle;
5 | display: inline;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/app/shared/circle-bar-spinner/circle-bar-spinner.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { CircleBarSpinnerComponent } from './circle-bar-spinner.component';
4 |
5 | describe('CircleBarSpinnerComponent', () => {
6 | let component: CircleBarSpinnerComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [CircleBarSpinnerComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(CircleBarSpinnerComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/shared/circle-bar-spinner/circle-bar-spinner.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-circle-bar-spinner',
5 | templateUrl: './circle-bar-spinner.component.html',
6 | styleUrls: ['./circle-bar-spinner.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class CircleBarSpinnerComponent {
10 | @Input() showSpinner: boolean;
11 |
12 | @Input() color = '#333333';
13 | }
14 |
--------------------------------------------------------------------------------
/src/app/shared/components/advanced-search/advanced-search.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { AdvancedSearchComponent } from './advanced-search.component';
4 |
5 | describe('AdvancedSearchComponent', () => {
6 | let component: AdvancedSearchComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [AdvancedSearchComponent],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(AdvancedSearchComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/app/shared/components/bitcoin-form/bitcoin-form.component.html:
--------------------------------------------------------------------------------
1 |
26 |
--------------------------------------------------------------------------------
/src/app/shared/components/bitcoin-form/bitcoin-form.component.scss:
--------------------------------------------------------------------------------
1 | [type='radio'] {
2 | -webkit-appearance: none;
3 | }
4 |
--------------------------------------------------------------------------------
/src/app/shared/components/bitcoin-form/bitcoin-form.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { BitcoinFormComponent } from './bitcoin-form.component';
4 |
5 | describe('BitcoinFormComponent', () => {
6 | let component: BitcoinFormComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [BitcoinFormComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(BitcoinFormComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/shared/components/bitcoin-form/bitcoin-form.component.ts:
--------------------------------------------------------------------------------
1 | import { Component } from '@angular/core';
2 |
3 | import { apiUrl } from '../../config';
4 |
5 | @Component({
6 | selector: 'app-bitcoin-form',
7 | templateUrl: './bitcoin-form.component.html',
8 | styleUrls: ['./bitcoin-form.component.scss'],
9 | })
10 | export class BitcoinFormComponent {
11 | public apiUrl: string = apiUrl;
12 | }
13 |
--------------------------------------------------------------------------------
/src/app/shared/components/countdown-timer/countdown-timer.component.html:
--------------------------------------------------------------------------------
1 | {{ days | async }} Day{{ (days | async) === 1 ? '' : 's' }} {{ hours | async }} Hour{{
3 | (hours | async) === 1 ? '' : 's'
4 | }}
5 | {{ minutes | async }} Minute{{ (minutes | async) === 1 ? '' : 's' }} {{ seconds | async }} Second{{
6 | (seconds | async) === 1 ? '' : 's'
7 | }}
8 |
9 |
--------------------------------------------------------------------------------
/src/app/shared/components/countdown-timer/countdown-timer.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/shared/components/countdown-timer/countdown-timer.component.scss
--------------------------------------------------------------------------------
/src/app/shared/components/custom-dropdown/custom-dropdown.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/app/shared/components/custom-dropdown/custom-dropdown.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/shared/components/custom-dropdown/custom-dropdown.component.scss
--------------------------------------------------------------------------------
/src/app/shared/components/loading-spinner/loading-spinner.component.html:
--------------------------------------------------------------------------------
1 |
2 |
30 |
31 |
--------------------------------------------------------------------------------
/src/app/shared/components/loading-spinner/loading-spinner.component.scss:
--------------------------------------------------------------------------------
1 | @import '~styles/base/variables';
2 |
3 | .loader {
4 | display: inline-block;
5 | vertical-align: top;
6 | }
7 |
8 | /*
9 | Set the color of the icon
10 | */
11 | svg rect {
12 | fill: $brand-blue;
13 | }
14 |
--------------------------------------------------------------------------------
/src/app/shared/components/loading-spinner/loading-spinner.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-loading-spinner',
5 | templateUrl: './loading-spinner.component.html',
6 | styleUrls: ['./loading-spinner.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class LoadingSpinnerComponent {
10 | @Input() showSpinner: boolean;
11 |
12 | @Input() optionalClasses = '';
13 |
14 | // Width and Height in Pixel unit
15 | @Input() width = 40;
16 |
17 | @Input() height = 40;
18 |
19 | @Input() color = '#3a4e63';
20 | }
21 |
--------------------------------------------------------------------------------
/src/app/shared/components/loading/loading.component.html:
--------------------------------------------------------------------------------
1 |
19 |
20 |
![]()
21 |
{{ quote.content }}
22 |
{{ quote.author }}
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/app/shared/components/loading/loading.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/shared/components/loading/loading.component.scss
--------------------------------------------------------------------------------
/src/app/shared/components/loading/loading.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { LoadingComponent } from './loading.component';
4 |
5 | describe('LoadingComponent', () => {
6 | let component: LoadingComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [LoadingComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(LoadingComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/shared/components/loading/loading.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
2 |
3 | import { LOADING_IMAGE } from '../../../store/services';
4 |
5 | @Component({
6 | selector: 'app-loading',
7 | templateUrl: './loading.component.html',
8 | styleUrls: ['./loading.component.scss'],
9 | changeDetection: ChangeDetectionStrategy.OnPush,
10 | })
11 | export class LoadingComponent {
12 | @Input() isLoading?: boolean;
13 |
14 | @Input() quote?: any;
15 |
16 | loadingImage = LOADING_IMAGE;
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/shared/components/progress-bar/progress-bar.component.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/src/app/shared/components/progress-bar/progress-bar.component.scss:
--------------------------------------------------------------------------------
1 | /* Progress Bar */
2 |
3 | $progress-bar-color: #e74c3c !default;
4 | .loader {
5 | height: 3px;
6 | width: 100%;
7 | position: relative;
8 | overflow: hidden;
9 | background-color: lighten($progress-bar-color, 40%);
10 | }
11 |
12 | .loader:before {
13 | display: block;
14 | position: absolute;
15 | content: '';
16 | left: -200px;
17 | width: 200px;
18 | height: 4px;
19 | background-color: $progress-bar-color;
20 | animation: loading 2s linear infinite;
21 | }
22 |
23 | @keyframes loading {
24 | from {
25 | left: -200px;
26 | width: 30%;
27 | }
28 | 50% {
29 | width: 30%;
30 | }
31 | 70% {
32 | width: 70%;
33 | }
34 | 80% {
35 | left: 50%;
36 | }
37 | 95% {
38 | left: 120%;
39 | }
40 | to {
41 | left: 100%;
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/src/app/shared/components/progress-bar/progress-bar.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input, ChangeDetectionStrategy } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-progress-bar',
5 | templateUrl: './progress-bar.component.html',
6 | styleUrls: ['./progress-bar.component.scss'],
7 | changeDetection: ChangeDetectionStrategy.OnPush,
8 | })
9 | export class ProgressBarComponent {
10 | @Input() active: boolean;
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/shared/components/spinner-image/spinner-image.component.html:
--------------------------------------------------------------------------------
1 |
2 |

3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/app/shared/components/spinner-image/spinner-image.component.scss:
--------------------------------------------------------------------------------
1 | .loader-area {
2 | display: flex;
3 | justify-content: center;
4 | align-items: center;
5 | }
6 |
7 | .logo-img {
8 | width: 60%;
9 | }
10 |
--------------------------------------------------------------------------------
/src/app/shared/components/spinner-image/spinner-image.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { SpinnerImageComponent } from './spinner-image.component';
4 |
5 | describe('SpinnerImageComponent', () => {
6 | let component: SpinnerImageComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [SpinnerImageComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(SpinnerImageComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/shared/components/spinner-image/spinner-image.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, Input } from '@angular/core';
2 |
3 | @Component({
4 | selector: 'app-spinner-image',
5 | templateUrl: './spinner-image.component.html',
6 | styleUrls: ['./spinner-image.component.scss'],
7 | })
8 | export class SpinnerImageComponent {
9 | isLoaded = false;
10 |
11 | @Input() src: string;
12 |
13 | @Input() class: string;
14 | }
15 |
--------------------------------------------------------------------------------
/src/app/shared/components/stripe-form/stripe-form.component.scss:
--------------------------------------------------------------------------------
1 | [class*='number'] .number.stripe-error,
2 | [class*='exp_year'] .exp_year.stripe-error,
3 | [class*='exp_month'] .exp_month.stripe-error,
4 | [class*='cvc'] .cvc.stripe-error {
5 | border-color: #c0392b;
6 | color: #c0392b;
7 | }
8 |
9 | [type='radio'] {
10 | -webkit-appearance: none;
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/shared/components/users-billing-info/users-billing-info.component.scss:
--------------------------------------------------------------------------------
1 | [class*='number'] .number.stripe-error,
2 | [class*='exp_year'] .exp_year.stripe-error,
3 | [class*='exp_month'] .exp_month.stripe-error,
4 | [class*='cvc'] .cvc.stripe-error {
5 | border-color: #c0392b;
6 | color: #c0392b;
7 | }
8 |
9 | .form-card-holder {
10 | max-width: 600px;
11 | }
12 |
13 | .cancel-subscription {
14 | margin-top: -2rem;
15 | margin-bottom: 2rem;
16 | text-align: left;
17 | }
18 |
19 | .promo-code-spinner {
20 | position: absolute;
21 | top: 3px;
22 | right: -30px;
23 | }
24 |
25 | .error-block {
26 | min-height: 20px;
27 | }
28 |
29 | .validate-promo-code {
30 | position: absolute;
31 | right: 0.75rem;
32 | top: 0;
33 | }
34 |
35 | .btn-dropdown-select .dropdown-menu {
36 | max-height: 300px;
37 | overflow-y: scroll;
38 | }
39 |
--------------------------------------------------------------------------------
/src/app/shared/components/users-billing-info/users-billing-info.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { UsersBillingInfoComponent } from './users-billing-info.component';
4 |
5 | describe('UsersBillingInfoComponent', () => {
6 | let component: UsersBillingInfoComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [UsersBillingInfoComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(UsersBillingInfoComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/shared/directives/anchor-scroll.directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, Input, AfterViewInit } from '@angular/core';
2 | import { ActivatedRoute } from '@angular/router';
3 | import { scrollIntoView } from '../util/dom-utils';
4 |
5 | @Directive({
6 | selector: 'a[anchorScroll]',
7 | })
8 | export class AnchorScrollDirective implements AfterViewInit {
9 | constructor(private route: ActivatedRoute) {}
10 |
11 | @Input()
12 | fragment: string;
13 |
14 | // wait for DOM to be ready for scrolling.
15 | // Also this directive executing means that our target anchor is also ready
16 | ngAfterViewInit(): void {
17 | if (this.route?.snapshot?.fragment === this.fragment) {
18 | setTimeout(() => {
19 | scrollIntoView(document.querySelector(`#${this.fragment}`));
20 | });
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/shared/directives/is-ie.directive.ts:
--------------------------------------------------------------------------------
1 | import { Directive, ViewContainerRef, TemplateRef, Input } from '@angular/core';
2 |
3 | import { BrowserDetectorService } from '../services/browser-detector.service';
4 |
5 | @Directive({
6 | selector: '[showInIE]',
7 | })
8 | export class IsIeDirective {
9 | constructor(
10 | private templateReference: TemplateRef,
11 | private viewContainer: ViewContainerRef,
12 | private browserDetector: BrowserDetectorService,
13 | ) {}
14 |
15 | @Input()
16 | set showInIE(value: boolean) {
17 | if (value) {
18 | if (this.browserDetector.isIEBrowser()) {
19 | this.viewContainer.createEmbeddedView(this.templateReference);
20 | } else {
21 | this.viewContainer.clear();
22 | }
23 | } else if (!this.browserDetector.isIEBrowser()) {
24 | this.viewContainer.createEmbeddedView(this.templateReference);
25 | } else {
26 | this.viewContainer.clear();
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/app/shared/pipes/creditcard-number.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | @Pipe({
4 | name: 'creditcardnumber',
5 | })
6 | export class CreditCardNumberPipe implements PipeTransform {
7 | transform(plainCreditCard: string): string {
8 | const defaultCardNumberLength = 16;
9 | if (plainCreditCard.length < 16) {
10 | plainCreditCard = plainCreditCard.padStart(defaultCardNumberLength, '0');
11 | }
12 | return plainCreditCard
13 | .replace(/\s+/g, '')
14 | .replace(/(\d{4})/g, '$1 ')
15 | .replace(/\d{4}(?= \d{4})/g, 'xxxx')
16 | .trim();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/app/shared/pipes/filename.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | @Pipe({
4 | name: 'filename',
5 | })
6 | export class FilenamePipe implements PipeTransform {
7 | static tranformToFilename(value: any) {
8 | if (!value) {
9 | return value;
10 | }
11 |
12 | const filePathTokens = value.split('/');
13 | return filePathTokens[filePathTokens.length - 1];
14 | }
15 |
16 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
17 | transform(value: any, arguments_?: any): any {
18 | return FilenamePipe.tranformToFilename(value);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/app/shared/pipes/filesize.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | @Pipe({
4 | name: 'filesize',
5 | })
6 | export class FilesizePipe implements PipeTransform {
7 | private units = ['B', 'KB', 'MB', 'GB', 'TB'];
8 |
9 | transform(bytes: any, preferredUnit?: any, precision = 2): any {
10 | if (Number.isNaN(Number.parseFloat(String(bytes))) || !Number.isFinite(bytes)) {
11 | return '?';
12 | }
13 |
14 | let unit = 0;
15 |
16 | // Check if preferred unit exist preset the unit
17 | if (preferredUnit && this.units.includes(preferredUnit)) {
18 | while (this.units[unit] !== preferredUnit) {
19 | unit += 1;
20 | }
21 | }
22 |
23 | while (bytes >= 1024) {
24 | bytes /= 1024;
25 |
26 | if (!preferredUnit) {
27 | unit += 1;
28 | }
29 | }
30 |
31 | return `${bytes.toFixed(+precision)} ${this.units[unit]}`;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/app/shared/pipes/last-action.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | import { MailAction } from '../../store/datatypes';
4 |
5 | @Pipe({
6 | name: 'lastAction',
7 | })
8 | export class LastActionPipe implements PipeTransform {
9 | // eslint-disable-next-line @typescript-eslint/no-unused-vars
10 | transform(value: MailAction, ...arguments_: any[]): any {
11 | switch (value) {
12 | case MailAction.FORWARD:
13 | return 'share';
14 | case MailAction.REPLY_ALL:
15 | return 'reply-all';
16 | default:
17 | return value.toLowerCase();
18 | }
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/app/shared/pipes/moment-date.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import * as moment from 'moment-timezone';
3 |
4 | import { DateTimeUtilService } from '../../store/services/datetime-util.service';
5 |
6 | @Pipe({
7 | name: 'momentDate',
8 | })
9 | export class MomentDatePipe implements PipeTransform {
10 | constructor(private dateTimeUtilService: DateTimeUtilService) {}
11 |
12 | transform(value: string, format = 'mediumDate', timezone?: string): string {
13 | if (value) {
14 | if (format === 'mail-list') {
15 | format = moment().isSame(moment(value), 'day') ? 'HH:mm' : 'MMM D, YYYY';
16 | }
17 | return this.dateTimeUtilService.formatDateTimeStr(value, format, timezone);
18 | }
19 | return '';
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/app/shared/pipes/replace-linebreak-brtag.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 |
3 | @Pipe({
4 | name: 'linebreaktobrtag',
5 | })
6 | export class LineBreakToBrTag implements PipeTransform {
7 | transform(mailContent: string): string {
8 | mailContent = mailContent.replace(/\r\n|\r|\n/g, '
');
9 | return mailContent;
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/app/shared/services/browser-detector.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 |
3 | @Injectable({
4 | providedIn: 'root',
5 | })
6 | export class BrowserDetectorService {
7 | isIEBrowser() {
8 | return !!this.checkIEVersion();
9 | }
10 |
11 | private checkIEVersion() {
12 | // Ref: https://stackoverflow.com/a/46116505/3502008
13 | const ua = window.navigator.userAgent;
14 |
15 | const msie = ua.indexOf('MSIE ');
16 | if (msie > 0) {
17 | // IE 10 or older => return version number
18 | // eslint-disable-next-line unicorn/prefer-string-slice
19 | return Number.parseInt(ua.substring(msie + 5, ua.indexOf('.', msie)), 10);
20 | }
21 |
22 | const trident = ua.indexOf('Trident/');
23 | if (trident > 0) {
24 | // IE 11 => return version number
25 | const rv = ua.indexOf('rv:');
26 | // eslint-disable-next-line unicorn/prefer-string-slice
27 | return Number.parseInt(ua.substring(rv + 3, ua.indexOf('.', rv)), 10);
28 | }
29 |
30 | // other browser
31 | return false;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/app/shared/services/key-manage.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { KeyManageService } from './key-manage.service';
4 |
5 | describe('KeyManageService', () => {
6 | let service: KeyManageService;
7 |
8 | beforeEach(() => {
9 | TestBed.configureTestingModule({});
10 | service = TestBed.inject(KeyManageService);
11 | });
12 |
13 | it('should be created', () => {
14 | expect(service).toBeTruthy();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/app/shared/services/key-manage.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable, OnDestroy } from '@angular/core';
2 | import { BehaviorSubject, Observable, Subject } from 'rxjs';
3 |
4 | @Injectable({
5 | providedIn: 'root',
6 | })
7 | export class KeyManageService implements OnDestroy {
8 | get ctrlAKeyTrigger$(): Observable {
9 | return this._ctrlAKeyTrigger$.asObservable();
10 | }
11 |
12 | private _ctrlAKeyTrigger$: Subject = new Subject();
13 |
14 | private destroy$ = new Subject();
15 |
16 | private isCtrlAPressed = false;
17 |
18 | constructor() {}
19 |
20 | public onPressCtrlAKey() {
21 | this._ctrlAKeyTrigger$.next(!this.isCtrlAPressed);
22 | this.isCtrlAPressed = !this.isCtrlAPressed;
23 | }
24 |
25 | ngOnDestroy(): void {
26 | this.destroy$.next();
27 | this.destroy$.complete();
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/app/shared/services/logger.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { LoggerService } from './logger.service';
4 |
5 | describe('LoggerService', () => {
6 | beforeEach(() => TestBed.configureTestingModule({}));
7 |
8 | it('should be created', () => {
9 | const service: LoggerService = TestBed.get(LoggerService);
10 | expect(service).toBeTruthy();
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/src/app/shared/services/logger.service.ts:
--------------------------------------------------------------------------------
1 | import { AppConfig } from '../../../environments/environment';
2 |
3 | export class LoggerService {
4 | public static log(message?: any, ...optionalParameters: any[]) {
5 | if (AppConfig.production === false) {
6 | console.log(message, optionalParameters);
7 | }
8 | }
9 |
10 | public static error(message?: any, ...optionalParameters: any[]) {
11 | if (AppConfig.production === false) {
12 | console.error(message, optionalParameters);
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/app/shared/services/push-notification.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { PushNotificationService } from './push-notification.service';
4 |
5 | describe('PushNotificationService', () => {
6 | beforeEach(() => TestBed.configureTestingModule({}));
7 |
8 | it('should be created', () => {
9 | const service: PushNotificationService = TestBed.get(PushNotificationService);
10 | expect(service).toBeTruthy();
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/src/app/shared/services/user-select-manage.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { UserSelectManageService } from './user-select-manage.service';
4 |
5 | describe('UserSelectManageService', () => {
6 | let service: UserSelectManageService;
7 |
8 | beforeEach(() => {
9 | TestBed.configureTestingModule({});
10 | service = TestBed.inject(UserSelectManageService);
11 | });
12 |
13 | it('should be created', () => {
14 | expect(service).toBeTruthy();
15 | });
16 | });
17 |
--------------------------------------------------------------------------------
/src/app/shared/services/user-select-manage.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Params } from '@angular/router';
3 | import { BehaviorSubject, Observable } from 'rxjs';
4 |
5 | @Injectable({
6 | providedIn: 'root',
7 | })
8 | export class UserSelectManageService {
9 | get userSelectPosibilityState$(): Observable {
10 | return this._userSelectPosibilityState$.asObservable();
11 | }
12 |
13 | private _userSelectPosibilityState$ = new BehaviorSubject(false);
14 | constructor() {}
15 |
16 | updateUserSelectPossiblilityState(isPossible: boolean) {
17 | this._userSelectPosibilityState$.next(isPossible);
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/src/app/shared/services/websocket.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed } from '@angular/core/testing';
2 |
3 | import { WebsocketService } from './websocket.service';
4 |
5 | describe('WebsocketService', () => {
6 | beforeEach(() => TestBed.configureTestingModule({}));
7 |
8 | it('should be created', () => {
9 | const service: WebsocketService = TestBed.get(WebsocketService);
10 | expect(service).toBeTruthy();
11 | });
12 | });
13 |
--------------------------------------------------------------------------------
/src/app/shared/spinner/components/spinner.component.html:
--------------------------------------------------------------------------------
1 |
2 |
![]()
3 |
4 |
5 |
--------------------------------------------------------------------------------
/src/app/shared/spinner/components/spinner.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/shared/spinner/components/spinner.component.scss
--------------------------------------------------------------------------------
/src/app/shared/spinner/components/spinner.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { SpinnerComponent } from './spinner.component';
4 |
5 | describe('SpinnerComponent', () => {
6 | let component: SpinnerComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [SpinnerComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(SpinnerComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/shared/spinner/components/spinner.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit, Input, OnDestroy, Output, EventEmitter } from '@angular/core';
2 |
3 | import { SpinnerService } from '../services/spinner.service';
4 |
5 | @Component({
6 | selector: 'app-spinner',
7 | templateUrl: './spinner.component.html',
8 | styleUrls: ['./spinner.component.scss'],
9 | })
10 | export class SpinnerComponent implements OnInit, OnDestroy {
11 | private isShowing = false;
12 |
13 | @Input() name: string;
14 |
15 | @Input() group: string;
16 |
17 | @Input() loadingImage: string;
18 |
19 | @Output() showChange = new EventEmitter();
20 |
21 | @Input()
22 | get show(): boolean {
23 | return this.isShowing;
24 | }
25 |
26 | set show(value: boolean) {
27 | this.isShowing = value;
28 | this.showChange.emit(this.isShowing);
29 | }
30 |
31 | constructor(private spinnerService: SpinnerService) {}
32 |
33 | ngOnInit() {
34 | if (!this.name) {
35 | throw new Error('Name attribute must be supplied for this spinner');
36 | }
37 |
38 | this.spinnerService.register(this);
39 | }
40 |
41 | ngOnDestroy(): void {
42 | this.spinnerService.unregister(this);
43 | }
44 | }
45 |
--------------------------------------------------------------------------------
/src/app/shared/spinner/services/spinner.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { SpinnerService } from './spinner.service';
4 |
5 | describe('SpinnerService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [SpinnerService],
9 | });
10 | });
11 |
12 | it('should be created', inject([SpinnerService], (service: SpinnerService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/src/app/shared/util/dom-utils.ts:
--------------------------------------------------------------------------------
1 | // Firefox cuts off top of the body when using scrollIntoView
2 | // Ctemplar display problem #437 fix by scroll the top of the page again
3 | export function scrollIntoView(element: HTMLElement): void {
4 | setTimeout(() => element?.scrollIntoView({ behavior: 'smooth' }));
5 | setTimeout(() => document.querySelector('app-mail')?.scrollIntoView(), 500);
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/shared/util/utils.ts:
--------------------------------------------------------------------------------
1 | export const intersection = (a: any[], b: any[]) => a?.filter((x: any) => b?.includes(x));
2 |
3 | export const difference = (a: any[], b: any[]) => a?.filter((x: any) => !b?.includes(x));
4 |
--------------------------------------------------------------------------------
/src/app/shared/validators/no-whitespace.validator.ts:
--------------------------------------------------------------------------------
1 | import { AbstractControl, ValidationErrors } from '@angular/forms';
2 |
3 | export const NoWhiteSpaceValidator = {
4 | noWhiteSpaceValidator(control: AbstractControl): ValidationErrors | null {
5 | if (((control.value as string) || '').trim().length === 0) {
6 | return { invalid: true };
7 | }
8 | return null;
9 | },
10 | };
11 |
--------------------------------------------------------------------------------
/src/app/store/actions/donate.actions.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 |
3 | export enum DonationActionTypes {
4 | MAKE_STRIPE_DONATION = '[DONATE] STRIPE DONATION',
5 | MAKE_STRIPE_DONATION_SUCCESS = '[DONATE] STRIPE DONATION SUCCESS',
6 | MAKE_STRIPE_DONATION_FAILURE = '[DONATE] STRIPE DONATION FAILURE',
7 | }
8 |
9 | export class MakeStripDonation implements Action {
10 | readonly type = DonationActionTypes.MAKE_STRIPE_DONATION;
11 |
12 | constructor(public payload: any) {}
13 | }
14 |
15 | export class MakeStripeDonationSuccess implements Action {
16 | readonly type = DonationActionTypes.MAKE_STRIPE_DONATION_SUCCESS;
17 |
18 | constructor(public payload: any) {}
19 | }
20 |
21 | export class MakeStripeDonationFailure implements Action {
22 | readonly type = DonationActionTypes.MAKE_STRIPE_DONATION_FAILURE;
23 |
24 | constructor(public payload: any) {}
25 | }
26 |
27 | export type DonateActionAll = MakeStripDonation | MakeStripeDonationSuccess | MakeStripeDonationFailure;
28 |
--------------------------------------------------------------------------------
/src/app/store/actions/index.ts:
--------------------------------------------------------------------------------
1 | export * from './router.action';
2 | export * from './auth.action';
3 | export * from './mail.actions';
4 | export * from './loading.action';
5 | export * from './keyboard.action';
6 | export * from './users.action';
7 | export * from './bitcoin.action';
8 | export * from './compose-mail.actions';
9 | export * from './secure-message.actions';
10 | export * from './donate.actions';
11 | export * from './contacts.action';
12 |
--------------------------------------------------------------------------------
/src/app/store/actions/keyboard.action.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 |
3 | export enum KeyboardActionTypes {
4 | KEYBOARD_FOCUSED = '[Keyboard] GetFocus',
5 | KEYBOARD_FOCUSED_OUT = '[Keyboard] GetFocusOut',
6 | KEY_PRESSED = '[Keyboard] KeyPressed',
7 | FOCUSED_INPUT = '[Keyboard] FocusedInput',
8 | }
9 |
10 | export class KeyboardFocus implements Action {
11 | readonly type = KeyboardActionTypes.KEYBOARD_FOCUSED;
12 |
13 | constructor(public payload: any) {}
14 | }
15 |
16 | export class KeyboardFocusOut implements Action {
17 | readonly type = KeyboardActionTypes.KEYBOARD_FOCUSED_OUT;
18 |
19 | constructor(public payload: any) {}
20 | }
21 |
22 | export class KeyPressed implements Action {
23 | readonly type = KeyboardActionTypes.KEY_PRESSED;
24 |
25 | constructor(public payload: any) {}
26 | }
27 |
28 | export class FocusedInputID implements Action {
29 | readonly type = KeyboardActionTypes.FOCUSED_INPUT;
30 |
31 | constructor(public payload: any) {}
32 | }
33 |
34 | export type KeyboardActionAll = KeyboardFocus | KeyboardFocusOut | KeyPressed | FocusedInputID;
35 |
--------------------------------------------------------------------------------
/src/app/store/actions/loading.action.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 |
3 | export enum LoadingActionTypes {
4 | RELATED_LOADING = '[Loading] Related Loading',
5 | RELATED_LOADED = '[Loading] Related Loaded',
6 | RECENT_LOADING = '[Loading] Recent Loading',
7 | RECENT_LOADED = '[Loading] Recent Loaded',
8 | FINAL_LOADING = '[Loading] Loading',
9 | }
10 |
11 | export class RelatedBlogLoading implements Action {
12 | readonly type = LoadingActionTypes.RELATED_LOADING;
13 |
14 | constructor(public payload: any) {}
15 | }
16 |
17 | export class RecentBlogLoading implements Action {
18 | readonly type = LoadingActionTypes.RECENT_LOADING;
19 |
20 | constructor(public payload: any) {}
21 | }
22 |
23 | export class FinalLoading implements Action {
24 | readonly type = LoadingActionTypes.FINAL_LOADING;
25 |
26 | constructor(public payload: any) {}
27 | }
28 |
29 | export type LoadingActionAll = RelatedBlogLoading | RecentBlogLoading | FinalLoading;
30 |
--------------------------------------------------------------------------------
/src/app/store/actions/router.action.ts:
--------------------------------------------------------------------------------
1 | import { NavigationExtras } from '@angular/router';
2 | import { Action } from '@ngrx/store';
3 |
4 | export const GO = '[Router] Go';
5 | export const BACK = '[Router] Back';
6 | export const FORWARD = '[Router] Forward';
7 |
8 | export class Go implements Action {
9 | readonly type = GO;
10 |
11 | constructor(
12 | public payload: {
13 | path: any[];
14 | query?: any;
15 | extras?: NavigationExtras;
16 | },
17 | ) {}
18 | }
19 |
20 | export class Back implements Action {
21 | readonly type = BACK;
22 | }
23 |
24 | export class Forward implements Action {
25 | readonly type = FORWARD;
26 | }
27 |
28 | export type Actions = Go | Back | Forward;
29 |
--------------------------------------------------------------------------------
/src/app/store/actions/search.action.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 |
3 | export enum SearchActionTypes {
4 | CLEAR_SEARCH = '[SEARCH] update',
5 | }
6 |
7 | export class ClearSearch implements Action {
8 | readonly type = SearchActionTypes.CLEAR_SEARCH;
9 |
10 | constructor(public payload?: any) {}
11 | }
12 |
13 | export type SearchActionAll = ClearSearch;
14 |
--------------------------------------------------------------------------------
/src/app/store/actions/timezone.action.ts:
--------------------------------------------------------------------------------
1 | import { Action } from '@ngrx/store';
2 |
3 | export enum TimezoneActionTypes {
4 | TIMEZONE_GET = '[TIMEZONE] GET',
5 | TIMEZONE_GET_SUCCESS = '[TIMEZONE] GET SUCCESS',
6 | }
7 |
8 | export class TimezoneGet implements Action {
9 | readonly type = TimezoneActionTypes.TIMEZONE_GET;
10 |
11 | constructor(public payload?: any) {}
12 | }
13 |
14 | export class TimezoneGetSuccess implements Action {
15 | readonly type = TimezoneActionTypes.TIMEZONE_GET_SUCCESS;
16 |
17 | constructor(public payload: any) {}
18 | }
19 |
20 | export type TimezoneActionAll = TimezoneGet | TimezoneGetSuccess;
21 |
--------------------------------------------------------------------------------
/src/app/store/effects/router.effect.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Router } from '@angular/router';
3 | import { Location } from '@angular/common';
4 | import { Effect, Actions, ofType } from '@ngrx/effects';
5 | import { tap, map } from 'rxjs/operators';
6 |
7 | import * as RouterActions from '../actions';
8 |
9 | @Injectable({
10 | providedIn: 'root',
11 | })
12 | export class RouterEffects {
13 | constructor(private actions$: Actions, private router: Router, private location: Location) {}
14 |
15 | @Effect({ dispatch: false })
16 | navigate$ = this.actions$.pipe(
17 | ofType(RouterActions.GO),
18 | map((action: RouterActions.Go) => action.payload),
19 | tap(({ path, query: queryParameters, extras }) => {
20 | this.router.navigate(path, { queryParams: queryParameters, ...extras });
21 | }),
22 | );
23 |
24 | @Effect({ dispatch: false })
25 | navigateBack$ = this.actions$.pipe(
26 | ofType(RouterActions.BACK),
27 | tap(() => this.location.back()),
28 | );
29 |
30 | @Effect({ dispatch: false })
31 | navigateForward$ = this.actions$.pipe(
32 | ofType(RouterActions.FORWARD),
33 | tap(() => this.location.forward()),
34 | );
35 | }
36 |
--------------------------------------------------------------------------------
/src/app/store/effects/timezone.effects.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Actions, Effect, ofType } from '@ngrx/effects';
3 | import { Observable, of } from 'rxjs';
4 | import { catchError, map, switchMap } from 'rxjs/operators';
5 |
6 | import { TimezoneActionTypes, TimezoneGet, TimezoneGetSuccess } from '../actions/timezone.action';
7 | import { TimezoneService } from '../services/timezone.service';
8 | import { SnackErrorPush } from '../actions';
9 |
10 | @Injectable({
11 | providedIn: 'root',
12 | })
13 | export class TimezoneEffects {
14 | constructor(private actions: Actions, private timezoneService: TimezoneService) {}
15 |
16 | @Effect()
17 | getTimezones: Observable = this.actions.pipe(
18 | ofType(TimezoneActionTypes.TIMEZONE_GET),
19 | map((action: TimezoneGet) => action.payload),
20 | switchMap(() => {
21 | return this.timezoneService.getTimezones().pipe(
22 | map(timezones => {
23 | return new TimezoneGetSuccess(timezones);
24 | }),
25 | catchError(() => of(new SnackErrorPush({ message: 'Failed to get timezones.' }))),
26 | );
27 | }),
28 | );
29 | }
30 |
--------------------------------------------------------------------------------
/src/app/store/index.ts:
--------------------------------------------------------------------------------
1 | export * from './actions';
2 | export * from './effects';
3 | export * from './reducers';
4 | export * from './selectors';
5 | export * from './websocket.store';
6 |
--------------------------------------------------------------------------------
/src/app/store/models/index.ts:
--------------------------------------------------------------------------------
1 | export * from './filter.model';
2 | export * from './mail.model';
3 | export * from './users.model';
4 |
--------------------------------------------------------------------------------
/src/app/store/reducers/donate.reducers.ts:
--------------------------------------------------------------------------------
1 | import { DonateActionAll, DonationActionTypes } from '../actions';
2 |
3 | export const initialState: any = {};
4 |
5 | export function reducer(state = initialState, action: DonateActionAll) {
6 | switch (action.type) {
7 | case DonationActionTypes.MAKE_STRIPE_DONATION:
8 | case DonationActionTypes.MAKE_STRIPE_DONATION_SUCCESS:
9 | case DonationActionTypes.MAKE_STRIPE_DONATION_FAILURE: {
10 | return state;
11 | }
12 |
13 | default: {
14 | return state;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/store/reducers/keyboard.reducers.ts:
--------------------------------------------------------------------------------
1 | import { KeyboardActionTypes, KeyboardActionAll } from '../actions';
2 | import { KeyboardState } from '../datatypes';
3 |
4 | export const initialState: KeyboardState = { keyboardFocused: false, keyPressed: { key: '' }, focusedInput: '' };
5 |
6 | export function reducer(state = initialState, action: KeyboardActionAll): KeyboardState {
7 | switch (action.type) {
8 | case KeyboardActionTypes.KEYBOARD_FOCUSED: {
9 | if (action.payload.keyboard === false) {
10 | return { ...state, keyboardFocused: false };
11 | }
12 | return { ...state, keyboardFocused: !state.keyboardFocused };
13 | }
14 | case KeyboardActionTypes.KEYBOARD_FOCUSED_OUT: {
15 | return initialState;
16 | }
17 | case KeyboardActionTypes.KEY_PRESSED: {
18 | return { ...state, keyPressed: action.payload };
19 | }
20 | case KeyboardActionTypes.FOCUSED_INPUT: {
21 | return { ...state, focusedInput: action.payload };
22 | }
23 | default: {
24 | return state;
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/src/app/store/reducers/loading.reducers.ts:
--------------------------------------------------------------------------------
1 | import { LoadingActionAll, LoadingActionTypes } from '../actions';
2 | import { LoadingState } from '../datatypes';
3 |
4 | export const initialState: LoadingState = {
5 | RecentBlogLoading: false,
6 | RelatedBlogLoading: false,
7 | Loading: false,
8 | };
9 |
10 | export function reducer(state = initialState, action: LoadingActionAll): LoadingState {
11 | switch (action.type) {
12 | case LoadingActionTypes.RECENT_LOADING: {
13 | return { ...state, RecentBlogLoading: action.payload.loadingState };
14 | }
15 | case LoadingActionTypes.RELATED_LOADING: {
16 | return { ...state, RelatedBlogLoading: action.payload.loadingState };
17 | }
18 | case LoadingActionTypes.FINAL_LOADING: {
19 | return { ...state, Loading: action.payload.loadingState };
20 | }
21 | default: {
22 | return state;
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/src/app/store/reducers/search.reducers.ts:
--------------------------------------------------------------------------------
1 | import { SearchActionAll, SearchActionTypes } from '../actions/search.action';
2 |
3 | export interface SearchState {
4 | searchText: string;
5 | }
6 |
7 | export const initialState: SearchState = { searchText: '' };
8 |
9 | export function reducer(state = initialState, action: SearchActionAll): SearchState {
10 | switch (action.type) {
11 | case SearchActionTypes.CLEAR_SEARCH: {
12 | return { ...state };
13 | }
14 | default: {
15 | return state;
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/app/store/reducers/timezone.reducer.ts:
--------------------------------------------------------------------------------
1 | import { TimezonesState } from '../datatypes';
2 | import { TimezoneActionAll, TimezoneActionTypes } from '../actions/timezone.action';
3 |
4 | // eslint-disable-next-line unicorn/no-object-as-default-parameter
5 | export function reducer(state: any = { timezones: [] }, action: TimezoneActionAll): TimezonesState {
6 | switch (action.type) {
7 | case TimezoneActionTypes.TIMEZONE_GET_SUCCESS: {
8 | return {
9 | ...state,
10 | timezones: action.payload,
11 | };
12 | }
13 | default: {
14 | return state;
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/store/selectors/index.ts:
--------------------------------------------------------------------------------
1 | import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
2 | import * as fromRouter from '@ngrx/router-store';
3 | import { Injectable } from '@angular/core';
4 |
5 | import { RouterStateUrl } from '../datatypes';
6 |
7 | @Injectable({
8 | providedIn: 'root',
9 | })
10 | export class CustomSerializer implements fromRouter.RouterStateSerializer {
11 | serialize(routerState: RouterStateSnapshot): RouterStateUrl {
12 | const { url, root } = routerState;
13 | const { queryParams } = root;
14 |
15 | let state: ActivatedRouteSnapshot = root;
16 | while (state.firstChild) {
17 | state = state.firstChild;
18 | }
19 | const { params } = state;
20 |
21 | return { url, queryParams, params, state };
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/store/services/auth.guard.ts:
--------------------------------------------------------------------------------
1 | import { ActivatedRouteSnapshot, CanActivate, Router, RouterStateSnapshot } from '@angular/router';
2 | import { Injectable } from '@angular/core';
3 |
4 | import { UsersService } from './users.service';
5 |
6 | @Injectable({
7 | providedIn: 'root',
8 | })
9 | export class AuthGuard implements CanActivate {
10 | constructor(private usersService: UsersService, private router: Router) {}
11 |
12 | canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
13 | if (this.usersService.getUserKey()) {
14 | if (state.url === '/signin') {
15 | this.router.navigateByUrl('/mail');
16 | }
17 | return true;
18 | }
19 | if (state.url === '/signin') {
20 | return true;
21 | }
22 | if (state.url.includes('/mail/')) {
23 | localStorage.setItem('nextPage', state.url);
24 | }
25 | this.router.navigateByUrl('/signin');
26 | return false;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/app/store/services/bitcoin.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 |
4 | import { apiUrl } from '../../shared/config';
5 |
6 | @Injectable({
7 | providedIn: 'root',
8 | })
9 | export class BitcoinService {
10 | constructor(private http: HttpClient) {}
11 |
12 | createNewWallet(data: any) {
13 | return this.http.post(`${apiUrl}btc-wallet/create/`, data);
14 | }
15 |
16 | checkTransaction(data: any) {
17 | return this.http.get(
18 | `${apiUrl}btc-wallet/check/?address=${data.from_address}${
19 | data.promo_code ? `&promo_code=${data.promo_code}` : ''
20 | }`,
21 | );
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/store/services/cancel.request.interceptor.ts:
--------------------------------------------------------------------------------
1 | import { Observable } from 'rxjs';
2 | import { takeUntil } from 'rxjs/operators';
3 | import { Injectable } from '@angular/core';
4 | import { HttpEvent, HttpHandler, HttpInterceptor, HttpRequest } from '@angular/common/http';
5 |
6 | import { HttpCancelService } from './cancel.request.service';
7 |
8 | @Injectable({
9 | providedIn: 'root',
10 | })
11 | export class CancelPendingRequestInterceptor implements HttpInterceptor {
12 | constructor(private httpCancelService: HttpCancelService) {}
13 |
14 | intercept(request: HttpRequest, next: HttpHandler): Observable> {
15 | return next.handle(request).pipe(takeUntil(this.httpCancelService.onCancelPendingRequests()));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/store/services/cancel.request.service.ts:
--------------------------------------------------------------------------------
1 | import { Subject } from 'rxjs';
2 | import { Injectable } from '@angular/core';
3 |
4 | @Injectable({
5 | providedIn: 'root',
6 | })
7 | export class HttpCancelService {
8 | private cancelPendingRequests$ = new Subject();
9 |
10 | /** Cancels all pending Http requests. */
11 | public cancelPendingRequests() {
12 | this.cancelPendingRequests$.next();
13 | }
14 |
15 | public onCancelPendingRequests() {
16 | return this.cancelPendingRequests$.asObservable();
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/src/app/store/services/donation.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { Observable } from 'rxjs';
4 |
5 | import { apiUrl } from '../../shared/config';
6 |
7 | @Injectable({
8 | providedIn: 'root',
9 | })
10 | export class DonationService {
11 | constructor(private http: HttpClient) {}
12 |
13 | /**
14 | * @description
15 | * Endpoint for accepting Stripe Donations
16 | *
17 | * @param data - stripe_token (required) | amount (required)
18 | */
19 | makeStripeDonation(data: any): Observable {
20 | return this.http.post(`${apiUrl}donate/stripe/`, data);
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/src/app/store/services/index.ts:
--------------------------------------------------------------------------------
1 | export * from './auth.guard';
2 | export * from './mail.service';
3 | export * from './openpgp.service';
4 | export * from './users.service';
5 | export * from './token.interceptor';
6 | export * from './shared.service';
7 | export * from './bitcoin.service';
8 | export * from './donation.service';
9 | export * from './cancel.request.interceptor';
10 | export * from './cancel.request.service';
11 | export * from './message.builder.service';
12 | export * from './message.decrypt.service';
13 | export * from './autocrypt.process.service';
14 | export * from './electron.service';
15 | export * from './export-mail.service';
16 | export * from './compose-mail.service';
17 | export * from './timezone.service';
18 | export * from './datetime-util.service';
19 | export * from './print-mail.service';
20 |
--------------------------------------------------------------------------------
/src/app/store/services/mail-settings.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Store } from '@ngrx/store';
3 |
4 | import { SettingsUpdate } from '../actions';
5 | import { AppState } from '../datatypes';
6 |
7 | @Injectable({
8 | providedIn: 'root',
9 | })
10 | export class MailSettingsService {
11 | constructor(private store: Store) {}
12 |
13 | updateSettings(settings: any, key?: string, value?: any) {
14 | if (key) {
15 | if (settings[key] !== value) {
16 | settings[key] = value;
17 | this.store.dispatch(new SettingsUpdate(settings));
18 | }
19 | } else {
20 | this.store.dispatch(new SettingsUpdate(settings));
21 | }
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/app/store/services/notification.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { MatSnackBar, MatSnackBarConfig } from '@angular/material/snack-bar';
3 | import { Store } from '@ngrx/store';
4 |
5 | import { AppState } from '../datatypes';
6 | import { UndoDeleteMail } from '../actions';
7 |
8 | @Injectable({
9 | providedIn: 'root',
10 | })
11 | export class NotificationService {
12 | constructor(private snackBar: MatSnackBar, private store: Store) {}
13 |
14 | showSnackBar(message: string, action = 'CLOSE', config: MatSnackBarConfig = undefined) {
15 | if (config === undefined) {
16 | config = { duration: 5000 };
17 | }
18 | this.snackBar.open(message, action, config);
19 | }
20 |
21 | showUndo(payload: any) {
22 | if (payload.sourceFolder) {
23 | const snackBarReference = this.snackBar.open(payload.message, 'Undo', { duration: 5000 });
24 |
25 | snackBarReference.onAction().subscribe(() => {
26 | this.store.dispatch(new UndoDeleteMail(payload));
27 | });
28 | } else {
29 | this.showSnackBar(payload.message);
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/app/store/services/timezone.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { HttpClient } from '@angular/common/http';
3 | import { map } from 'rxjs/operators';
4 |
5 | import { apiUrl } from '../../shared/config';
6 | import { Timezone } from '../datatypes';
7 |
8 | @Injectable({
9 | providedIn: 'root',
10 | })
11 | export class TimezoneService {
12 | constructor(private http: HttpClient) {}
13 |
14 | getTimezones() {
15 | return this.http.get(`${apiUrl}data/timezones/`).pipe(map((item: any) => item.timezones));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/users/dialogs/display-name-dialog/display-name-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .title {
2 | width: 290px;
3 | height: 40px;
4 | font-family: Lato;
5 | font-size: 24px;
6 | font-weight: bold;
7 | font-style: normal;
8 | font-stretch: normal;
9 | line-height: 1.67;
10 | letter-spacing: normal;
11 | text-align: center;
12 | color: rgba(0, 0, 0, 0.87);
13 | }
14 |
15 | .submit-display-name-btn {
16 | width: 151px;
17 | height: 48px;
18 | font-family: Lato;
19 | font-size: 16px;
20 | font-weight: bold;
21 | font-style: normal;
22 | font-stretch: normal;
23 | letter-spacing: 0.8px;
24 | text-align: center;
25 | color: #ffffff;
26 | }
27 |
28 | .modal-sm .modal-dialog .btn {
29 | font-size: 1.12rem !important;
30 | }
31 |
32 | .display-name-input {
33 | width: 504px;
34 | height: 48px;
35 | border-radius: 4px;
36 | border: solid 1px #e0e0e0;
37 | background-color: #ffffff;
38 | }
39 |
40 | .copy-btn {
41 | border: 0;
42 | cursor: pointer;
43 | float: right;
44 | }
45 |
46 | .skip-btn {
47 | cursor: pointer;
48 | position: absolute;
49 | left: 30px;
50 | }
51 | .skip-btn:hover {
52 | color: #000;
53 | }
54 |
--------------------------------------------------------------------------------
/src/app/users/dialogs/display-name-dialog/display-name-dialog.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { DisplayNameDialogComponent } from './display-name-dialog.component';
4 |
5 | describe('DisplayNameDialogComponent', () => {
6 | let component: DisplayNameDialogComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [DisplayNameDialogComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(DisplayNameDialogComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/users/dialogs/send-feedback-dialog/send-feedback-dialog.component.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/app/users/dialogs/send-feedback-dialog/send-feedback-dialog.component.scss
--------------------------------------------------------------------------------
/src/app/users/dialogs/send-feedback-dialog/send-feedback-dialog.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { SendFeedbackDialogComponent } from './send-feedback-dialog.component';
4 |
5 | describe('SendFeedbackDialogComponent', () => {
6 | let component: SendFeedbackDialogComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async () => {
10 | await TestBed.configureTestingModule({
11 | declarations: [SendFeedbackDialogComponent],
12 | }).compileComponents();
13 | });
14 |
15 | beforeEach(() => {
16 | fixture = TestBed.createComponent(SendFeedbackDialogComponent);
17 | component = fixture.componentInstance;
18 | fixture.detectChanges();
19 | });
20 |
21 | it('should create', () => {
22 | expect(component).toBeTruthy();
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/app/users/dialogs/use-cache-dialog/use-cache-dialog.component.scss:
--------------------------------------------------------------------------------
1 | .bottom-view {
2 | margin-left: 5px;
3 | margin-right: 5px;
4 | }
5 | .ask-more {
6 | flex: 1;
7 | }
8 | ::ng-deep .mat-checkbox .mat-checkbox-frame {
9 | border: 2px solid var(--mat-checkbox-border-color);
10 | }
11 | ::ng-deep .mat-checkbox .mat-checkbox-background {
12 | border: var(--width-0-2) solid var(--mat-checkbox-border-color);
13 | }
14 | .mat-checkbox-row {
15 | height: 24px;
16 | }
17 |
--------------------------------------------------------------------------------
/src/app/users/dialogs/use-cache-dialog/use-cache-dialog.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { UseCacheDialogComponent } from './use-cache-dialog.component';
4 |
5 | describe('UseCacheDialogComponent', () => {
6 | let component: UseCacheDialogComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [UseCacheDialogComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(UseCacheDialogComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/users/dialogs/user-account-init-dialog/user-account-init-dialog.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { UserAccountInitDialogComponent } from './user-account-init-dialog.component';
4 |
5 | describe('UserAccountInitDialogComponent', () => {
6 | let component: UserAccountInitDialogComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [UserAccountInitDialogComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(UserAccountInitDialogComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/users/users-create-account/users-create-account.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { UsersCreateAccountComponent } from './users-create-account.component';
4 |
5 | describe('UsersCreateAccountComponent', () => {
6 | let component: UsersCreateAccountComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [UsersCreateAccountComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(UsersCreateAccountComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/users/users-sign-up/users-sign-up.component.scss:
--------------------------------------------------------------------------------
1 | .dropdown-item {
2 | color: #292b2c !important;
3 | }
4 | .make-center {
5 | justify-content: center;
6 | }
7 |
--------------------------------------------------------------------------------
/src/app/users/users-sign-up/users-sign-up.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { ComponentFixture, TestBed, waitForAsync } from '@angular/core/testing';
2 |
3 | import { UsersSignUpComponent } from './users-sign-up.component';
4 |
5 | describe('UsersSignUpComponent', () => {
6 | let component: UsersSignUpComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(
10 | waitForAsync(() => {
11 | TestBed.configureTestingModule({
12 | declarations: [UsersSignUpComponent],
13 | }).compileComponents();
14 | }),
15 | );
16 |
17 | beforeEach(() => {
18 | fixture = TestBed.createComponent(UsersSignUpComponent);
19 | component = fixture.componentInstance;
20 | fixture.detectChanges();
21 | });
22 |
23 | it('should create', () => {
24 | expect(component).toBeTruthy();
25 | });
26 | });
27 |
--------------------------------------------------------------------------------
/src/app/users/users.module.spec.ts:
--------------------------------------------------------------------------------
1 | import { UsersModule } from './users.module';
2 |
3 | describe('UsersModule', () => {
4 | let usersModule: UsersModule;
5 |
6 | beforeEach(() => {
7 | usersModule = new UsersModule();
8 | });
9 |
10 | it('should create an instance', () => {
11 | expect(usersModule).toBeTruthy();
12 | });
13 | });
14 |
--------------------------------------------------------------------------------
/src/assets/fonts/ctemplar-fonts/autocrypt.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/ctemplar-fonts/autocrypt.eot
--------------------------------------------------------------------------------
/src/assets/fonts/ctemplar-fonts/autocrypt.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/ctemplar-fonts/autocrypt.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/ctemplar-fonts/autocrypt.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/ctemplar-fonts/autocrypt.woff
--------------------------------------------------------------------------------
/src/assets/fonts/ctemplar/ctemplar-icon-info-circle.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/ctemplar/ctemplar-icon-info-circle.eot
--------------------------------------------------------------------------------
/src/assets/fonts/ctemplar/ctemplar-icon-info-circle.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/src/assets/fonts/ctemplar/ctemplar-icon-info-circle.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/ctemplar/ctemplar-icon-info-circle.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/ctemplar/ctemplar-icon-info-circle.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/ctemplar/ctemplar-icon-info-circle.woff
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon/icomoon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/icomoon/icomoon.eot
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon/icomoon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/icomoon/icomoon.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon/icomoon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/icomoon/icomoon.woff
--------------------------------------------------------------------------------
/src/assets/fonts/icomoon/libs/icomoon.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/icomoon/libs/icomoon.zip
--------------------------------------------------------------------------------
/src/assets/fonts/lato/S6u9w4BMUTPHh50XSwaPGQ3q5d0N7w.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/lato/S6u9w4BMUTPHh50XSwaPGQ3q5d0N7w.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/lato/S6u9w4BMUTPHh50XSwiPGQ3q5d0.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/lato/S6u9w4BMUTPHh50XSwiPGQ3q5d0.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/lato/S6u9w4BMUTPHh6UVSwaPGQ3q5d0N7w.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/lato/S6u9w4BMUTPHh6UVSwaPGQ3q5d0N7w.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/lato/S6u9w4BMUTPHh6UVSwiPGQ3q5d0.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/lato/S6u9w4BMUTPHh6UVSwiPGQ3q5d0.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/lato/S6uyw4BMUTPHjx4wXiWtFCc.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/lato/S6uyw4BMUTPHjx4wXiWtFCc.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/lato/S6uyw4BMUTPHjxAwXiWtFCfQ7A.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/lato/S6uyw4BMUTPHjxAwXiWtFCfQ7A.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/lato/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/lato/flUhRq6tzZclQEJ-Vdg-IuiaDsNcIhQ8tQ.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Bold.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Bold.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Bold.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Italic.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Italic.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Italic.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Italic.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Light.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Light.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Light.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Regular.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Regular.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Lato-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Lato-Regular.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Roboto-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Roboto-Bold.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Roboto-Bold.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Roboto-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Roboto-Regular.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/Roboto-Regular.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-brands-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-brands-400.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-brands-400.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-brands-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-brands-400.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-brands-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-brands-400.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-regular-400.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-regular-400.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-regular-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-regular-400.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-regular-400.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-regular-400.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-regular-400.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-regular-400.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-solid-900.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-solid-900.eot
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-solid-900.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-solid-900.ttf
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-solid-900.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-solid-900.woff
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fa-solid-900.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fa-solid-900.woff2
--------------------------------------------------------------------------------
/src/assets/fonts/webfonts/fortfa-brands-400.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/fonts/webfonts/fortfa-brands-400.ttf
--------------------------------------------------------------------------------
/src/assets/icons/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/icons/favicon.ico
--------------------------------------------------------------------------------
/src/assets/icons/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/icons/icon.png
--------------------------------------------------------------------------------
/src/assets/icons/icon@512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/icons/icon@512.png
--------------------------------------------------------------------------------
/src/assets/icons/spinner.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/icons/warranty-canary.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/icons/warranty-canary.png
--------------------------------------------------------------------------------
/src/assets/images/account-creation-img.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/account-creation-img.jpg
--------------------------------------------------------------------------------
/src/assets/images/all-emails.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/images/blog/blog-banner.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/blog-banner.jpg
--------------------------------------------------------------------------------
/src/assets/images/blog/blog-img-1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/blog-img-1.jpg
--------------------------------------------------------------------------------
/src/assets/images/blog/blog-img-2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/blog-img-2.jpg
--------------------------------------------------------------------------------
/src/assets/images/blog/blog-img-3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/blog-img-3.jpg
--------------------------------------------------------------------------------
/src/assets/images/blog/blog-img-4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/blog-img-4.jpg
--------------------------------------------------------------------------------
/src/assets/images/blog/blog-img-5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/blog-img-5.jpg
--------------------------------------------------------------------------------
/src/assets/images/blog/blog-img-6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/blog-img-6.jpg
--------------------------------------------------------------------------------
/src/assets/images/blog/table_d-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/table_d-min.png
--------------------------------------------------------------------------------
/src/assets/images/blog/table_m_2x-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/table_m_2x-min.png
--------------------------------------------------------------------------------
/src/assets/images/blog/table_t-min.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/blog/table_t-min.png
--------------------------------------------------------------------------------
/src/assets/images/donate/bitcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/donate/bitcoin.png
--------------------------------------------------------------------------------
/src/assets/images/donate/donate-by-card.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/donate/donate-by-card.png
--------------------------------------------------------------------------------
/src/assets/images/features-icon/lock.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/images/features-icon/mobile.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/images/features-icon/shield.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/images/home/banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/home/banner.png
--------------------------------------------------------------------------------
/src/assets/images/home/hero-banner.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/home/hero-banner.png
--------------------------------------------------------------------------------
/src/assets/images/icon-reply.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/images/media-kit/mediakit-logo-sec.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/mediakit-logo-sec.png
--------------------------------------------------------------------------------
/src/assets/images/media-kit/mediakit-logo1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/mediakit-logo1.png
--------------------------------------------------------------------------------
/src/assets/images/media-kit/mediakit-logo2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/mediakit-logo2.png
--------------------------------------------------------------------------------
/src/assets/images/media-kit/mediakit-logo3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/mediakit-logo3.png
--------------------------------------------------------------------------------
/src/assets/images/media-kit/mediakit-logo4.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/mediakit-logo4.png
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img1.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img1.jpg
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img2.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img2.jpg
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img3.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img3.jpg
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img4.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img4.jpg
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img5.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img5.jpg
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img6.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img6.jpg
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img7.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img7.jpg
--------------------------------------------------------------------------------
/src/assets/images/media-kit/wallpaper-img8.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/media-kit/wallpaper-img8.jpg
--------------------------------------------------------------------------------
/src/assets/images/more_horiz_black_20dp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/more_horiz_black_20dp.png
--------------------------------------------------------------------------------
/src/assets/images/onions/onions-img.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/onions/onions-img.png
--------------------------------------------------------------------------------
/src/assets/images/onions/tor.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/onions/tor.png
--------------------------------------------------------------------------------
/src/assets/images/outbox.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/images/plus@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/plus@2x.png
--------------------------------------------------------------------------------
/src/assets/images/select-arrow.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/assets/images/user-actions/decrypt_message.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/user-actions/decrypt_message.png
--------------------------------------------------------------------------------
/src/assets/images/user-actions/login-bg.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/user-actions/login-bg.jpg
--------------------------------------------------------------------------------
/src/assets/images/user-icon-grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/images/user-icon-grey.png
--------------------------------------------------------------------------------
/src/assets/js/stripe-key.js:
--------------------------------------------------------------------------------
1 | Stripe.setPublishableKey('pk_live_1LuzdDnTEXzARPf1EqYVwfn7');
2 |
--------------------------------------------------------------------------------
/src/assets/js/stripe-test-key.js:
--------------------------------------------------------------------------------
1 | Stripe.setPublishableKey('pk_test_74VES8ynn6mJuUoBY3stNyD3');
2 |
--------------------------------------------------------------------------------
/src/assets/static/info-circle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/assets/static/info-circle.png
--------------------------------------------------------------------------------
/src/environments/environment.local.ts:
--------------------------------------------------------------------------------
1 | export const AppConfig = {
2 | debug: true,
3 | local: true,
4 | production: false,
5 | };
6 |
--------------------------------------------------------------------------------
/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const AppConfig = {
2 | debug: false,
3 | production: true,
4 | local: false,
5 | };
6 |
--------------------------------------------------------------------------------
/src/environments/environment.ts:
--------------------------------------------------------------------------------
1 | // The file contents for the current environment will overwrite these during build.
2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
4 | // The list of which env maps to which file can be found in `.angular-cli.json`.
5 |
6 | export const AppConfig = {
7 | debug: true,
8 | production: false,
9 | local: false,
10 | };
11 |
--------------------------------------------------------------------------------
/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { AppConfig } from './environments/environment';
6 |
7 | if (AppConfig.production) {
8 | enableProdMode();
9 | if (window) {
10 | window.console.log = () => {};
11 | window.console.error = () => {};
12 | }
13 | }
14 |
15 | platformBrowserDynamic()
16 | .bootstrapModule(AppModule, {
17 | preserveWhitespaces: false,
18 | })
19 | .catch(error => console.error(error));
20 |
--------------------------------------------------------------------------------
/src/styles/_themes.scss:
--------------------------------------------------------------------------------
1 | .theme-light {
2 | @each $name, $value in $variables {
3 | #{$name}: nth($value, 1);
4 | }
5 | }
6 |
7 | .theme-dark {
8 | @each $name, $value in $variables {
9 | #{$name}: nth($value, 2);
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/styles/layouts/_footer.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/CTemplar/webclient/d6be9eb7640abb2d6fa4ae3696c20a969cb72aaf/src/styles/layouts/_footer.scss
--------------------------------------------------------------------------------
/src/styles/modules/bootstrap-overrides/_alert.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstrap overrides :: alert scss file
3 | */
4 |
5 | // == Alert
6 | .l-alert {
7 | padding: 0.688rem 0.938rem;
8 | border: 1px solid #bdbdbd !important;
9 | border-radius: 2px;
10 | box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.12);
11 | color: $brand-black;
12 | font-size: 0.75rem;
13 | width: 100%;
14 |
15 | @include media('>sm') {
16 | padding: 0.688rem 1.563rem;
17 | }
18 |
19 | a {
20 | color: $brand-black;
21 | }
22 | }
23 |
24 | .l-alert-warning {
25 | background-color: #fff2df !important;
26 | }
27 |
28 | .l-alert-danger {
29 | background-color: #ffe1df !important;
30 | }
31 |
32 | .l-alert-success {
33 | background-color: #dff2ff !important;
34 | }
35 |
36 | .l-alert-is-floated {
37 | position: absolute;
38 | top: 0px;
39 | right: 0;
40 | left: 0;
41 | z-index: $zindex-default;
42 |
43 | @include media('>sm') {
44 | top: 77px;
45 | right: auto;
46 | left: 50%;
47 | transform: translateX(-50%);
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/src/styles/modules/bootstrap-overrides/_overrides.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Bootstrap overrides scss file which includes other partials
3 | */
4 |
5 | @import 'button';
6 | @import 'form';
7 | @import 'dropdown';
8 | @import 'modal';
9 | @import 'alert';
10 | @import 'tooltips';
11 |
12 | // == Text
13 | @include text-emphasis-variant('.text-dark', rgba(0, 0, 0, 0.87));
14 | @include text-emphasis-variant('.text-secondary', $brand-secondary);
15 | @include text-emphasis-variant('.text-secondary-faded', rgba(52, 73, 94, 0.87));
16 | @include text-emphasis-variant('.text-faded', #c4c4c4);
17 | @include text-emphasis-variant('.text-green', $brand-green);
18 |
19 | // == Background
20 | @include bg-variant('.bg-faded', $brand-faded);
21 | @include bg-variant('.bg-secondary', $brand-secondary);
22 | @include bg-variant('.bg-white', $brand-white);
23 |
--------------------------------------------------------------------------------
/src/styles/modules/cards/_cards.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Card modules scss file which includes reusable cards related style rules
3 | */
4 |
5 | @import 'post';
6 | @import 'single-post';
7 | @import 'package';
8 | @import 'square';
9 |
--------------------------------------------------------------------------------
/src/styles/modules/cards/_square.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Square card scss
3 | */
4 |
5 | .square-card {
6 | // position: relative;
7 | // overflow: hidden;
8 | // display: flex;
9 | // align-items: center;
10 | // justify-content: center;
11 | text-align: center;
12 |
13 | &::after {
14 | display: block;
15 | content: '';
16 | padding-bottom: 100%;
17 | }
18 |
19 | &.has-border {
20 | border: 1px solid $input-border-color;
21 | }
22 | }
23 |
24 | .square-card-content {
25 | position: absolute;
26 | top: 2.813rem;
27 | padding: 0 1.25rem;
28 | }
29 |
30 | .square-card-footer {
31 | position: absolute;
32 | bottom: 0.938rem;
33 | padding: 0 1.25rem;
34 | font-size: 0.875rem;
35 | }
36 |
--------------------------------------------------------------------------------
/src/styles/modules/utilities/_utilities.scss:
--------------------------------------------------------------------------------
1 | /**
2 | * Utilities sass file to import other utilities partials sass files
3 | */
4 |
5 | @import 'form-fields';
6 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_close.scss:
--------------------------------------------------------------------------------
1 | .close {
2 | float: right;
3 | font-size: $close-font-size;
4 | font-weight: $close-font-weight;
5 | line-height: 1;
6 | color: var(--close-color);
7 | text-shadow: $close-text-shadow;
8 | opacity: 0.5;
9 |
10 | @include hover-focus {
11 | color: var(--close-color);
12 | text-decoration: none;
13 | cursor: pointer;
14 | opacity: 0.75;
15 | }
16 | }
17 |
18 | // Additional properties for button version
19 | // iOS requires the button element instead of an anchor tag.
20 | // If you want the anchor version, it requires `href="#"`.
21 | // See https://developer.mozilla.org/en-US/docs/Web/Events/click#Safari_Mobile
22 |
23 | // scss-lint:disable QualifyingElement
24 | button.close {
25 | padding: 0;
26 | cursor: pointer;
27 | background: transparent;
28 | border: 0;
29 | -webkit-appearance: none;
30 | }
31 | // scss-lint:enable QualifyingElement
32 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_custom.scss:
--------------------------------------------------------------------------------
1 | // Bootstrap overrides
2 | //
3 | // Copy variables from `_variables.scss` to this file to override default values
4 | // without modifying source files.
5 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_jumbotron.scss:
--------------------------------------------------------------------------------
1 | .jumbotron {
2 | padding: $jumbotron-padding ($jumbotron-padding / 2);
3 | margin-bottom: $jumbotron-padding;
4 | background-color: $jumbotron-bg;
5 | @include border-radius($border-radius-lg);
6 |
7 | @include media-breakpoint-up(sm) {
8 | padding: ($jumbotron-padding * 2) $jumbotron-padding;
9 | }
10 | }
11 |
12 | .jumbotron-hr {
13 | border-top-color: darken($jumbotron-bg, 10%);
14 | }
15 |
16 | .jumbotron-fluid {
17 | padding-right: 0;
18 | padding-left: 0;
19 | @include border-radius(0);
20 | }
21 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_media.scss:
--------------------------------------------------------------------------------
1 | .media {
2 | display: flex;
3 | align-items: flex-start;
4 | }
5 |
6 | .media-body {
7 | flex: 1;
8 | }
9 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_progress.scss:
--------------------------------------------------------------------------------
1 | // Progress animations
2 | @keyframes progress-bar-stripes {
3 | from {
4 | background-position: $progress-height 0;
5 | }
6 | to {
7 | background-position: 0 0;
8 | }
9 | }
10 |
11 | // Basic progress bar
12 | .progress {
13 | display: flex;
14 | overflow: hidden; // force rounded corners by cropping it
15 | font-size: $progress-font-size;
16 | line-height: $progress-height;
17 | text-align: center;
18 | background-color: $progress-bg;
19 | @include border-radius($progress-border-radius);
20 | }
21 | .progress-bar {
22 | height: $progress-height;
23 | color: $progress-bar-color;
24 | background-color: $progress-bar-bg;
25 | }
26 |
27 | // Striped
28 | .progress-bar-striped {
29 | @include gradient-striped();
30 | background-size: $progress-height $progress-height;
31 | }
32 |
33 | // Animated
34 | .progress-bar-animated {
35 | animation: progress-bar-stripes $progress-bar-animation-timing;
36 | }
37 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_responsive-embed.scss:
--------------------------------------------------------------------------------
1 | // Credit: Nicolas Gallagher and SUIT CSS.
2 |
3 | .embed-responsive {
4 | position: relative;
5 | display: block;
6 | width: 100%;
7 | padding: 0;
8 | overflow: hidden;
9 |
10 | &::before {
11 | display: block;
12 | content: '';
13 | }
14 |
15 | .embed-responsive-item,
16 | iframe,
17 | embed,
18 | object,
19 | video {
20 | position: absolute;
21 | top: 0;
22 | bottom: 0;
23 | left: 0;
24 | width: 100%;
25 | height: 100%;
26 | border: 0;
27 | }
28 | }
29 |
30 | .embed-responsive-21by9 {
31 | &::before {
32 | padding-top: percentage(9 / 21);
33 | }
34 | }
35 |
36 | .embed-responsive-16by9 {
37 | &::before {
38 | padding-top: percentage(9 / 16);
39 | }
40 | }
41 |
42 | .embed-responsive-4by3 {
43 | &::before {
44 | padding-top: percentage(3 / 4);
45 | }
46 | }
47 |
48 | .embed-responsive-1by1 {
49 | &::before {
50 | padding-top: percentage(1 / 1);
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_transitions.scss:
--------------------------------------------------------------------------------
1 | .fade {
2 | opacity: 0;
3 | @include transition($transition-fade);
4 |
5 | &.show {
6 | opacity: 1;
7 | }
8 | }
9 |
10 | .collapse {
11 | display: none;
12 | &.show {
13 | display: block;
14 | }
15 | }
16 |
17 | tr {
18 | &.collapse.show {
19 | display: table-row;
20 | }
21 | }
22 |
23 | tbody {
24 | &.collapse.show {
25 | display: table-row-group;
26 | }
27 | }
28 |
29 | .collapsing {
30 | position: relative;
31 | height: 0;
32 | overflow: hidden;
33 | @include transition($transition-collapse);
34 | }
35 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/_utilities.scss:
--------------------------------------------------------------------------------
1 | @import 'utilities/align';
2 | @import 'utilities/background';
3 | @import 'utilities/borders';
4 | @import 'utilities/clearfix';
5 | @import 'utilities/display';
6 | @import 'utilities/flex';
7 | @import 'utilities/float';
8 | @import 'utilities/position';
9 | @import 'utilities/screenreaders';
10 | @import 'utilities/sizing';
11 | @import 'utilities/spacing';
12 | @import 'utilities/text';
13 | @import 'utilities/visibility';
14 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_alert.scss:
--------------------------------------------------------------------------------
1 | // Alerts
2 |
3 | @mixin alert-variant($background, $border, $body-color) {
4 | background-color: $background;
5 | border-color: $border;
6 | color: var(--body-color);
7 |
8 | hr {
9 | border-top-color: darken($border, 5%);
10 | }
11 | .alert-link {
12 | color: darken($body-color, 10%);
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_background-variant.scss:
--------------------------------------------------------------------------------
1 | // Contextual backgrounds
2 |
3 | @mixin bg-variant($parent, $color) {
4 | #{$parent} {
5 | background-color: $color !important;
6 | }
7 | a#{$parent} {
8 | @include hover-focus {
9 | background-color: darken($color, 10%) !important;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_badge.scss:
--------------------------------------------------------------------------------
1 | // Badges
2 |
3 | @mixin badge-variant($color) {
4 | background-color: $color;
5 |
6 | &[href] {
7 | @include hover-focus {
8 | background-color: darken($color, 10%);
9 | }
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_border-radius.scss:
--------------------------------------------------------------------------------
1 | // Single side border-radius
2 |
3 | @mixin border-radius($radius: $border-radius) {
4 | @if $enable-rounded {
5 | border-radius: $radius;
6 | }
7 | }
8 |
9 | @mixin border-top-radius($radius) {
10 | @if $enable-rounded {
11 | border-top-right-radius: $radius;
12 | border-top-left-radius: $radius;
13 | }
14 | }
15 |
16 | @mixin border-right-radius($radius) {
17 | @if $enable-rounded {
18 | border-bottom-right-radius: $radius;
19 | border-top-right-radius: $radius;
20 | }
21 | }
22 |
23 | @mixin border-bottom-radius($radius) {
24 | @if $enable-rounded {
25 | border-bottom-right-radius: $radius;
26 | border-bottom-left-radius: $radius;
27 | }
28 | }
29 |
30 | @mixin border-left-radius($radius) {
31 | @if $enable-rounded {
32 | border-bottom-left-radius: $radius;
33 | border-top-left-radius: $radius;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_cards.scss:
--------------------------------------------------------------------------------
1 | // Card variants
2 |
3 | @mixin card-variant($background, $border) {
4 | background-color: $background;
5 | border-color: $border;
6 |
7 | .card-header,
8 | .card-footer {
9 | background-color: transparent;
10 | }
11 | }
12 |
13 | @mixin card-outline-variant($color) {
14 | background-color: transparent;
15 | border-color: $color;
16 | }
17 |
18 | //
19 | // Inverse text within a card for use with dark backgrounds
20 | //
21 |
22 | @mixin card-inverse {
23 | color: rgba(255, 255, 255, 0.65);
24 |
25 | .card-header,
26 | .card-footer {
27 | background-color: transparent;
28 | border-color: rgba(255, 255, 255, 0.2);
29 | }
30 | .card-header,
31 | .card-footer,
32 | .card-title,
33 | .card-blockquote {
34 | color: #fff;
35 | }
36 | .card-link,
37 | .card-text,
38 | .card-subtitle,
39 | .card-blockquote .blockquote-footer {
40 | color: rgba(255, 255, 255, 0.65);
41 | }
42 | .card-link {
43 | @include hover-focus {
44 | color: $card-link-hover-color;
45 | }
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_clearfix.scss:
--------------------------------------------------------------------------------
1 | @mixin clearfix() {
2 | &::after {
3 | display: block;
4 | content: '';
5 | clear: both;
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_float.scss:
--------------------------------------------------------------------------------
1 | @mixin float-left {
2 | float: left !important;
3 | }
4 | @mixin float-right {
5 | float: right !important;
6 | }
7 | @mixin float-none {
8 | float: none !important;
9 | }
10 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_image.scss:
--------------------------------------------------------------------------------
1 | // Image Mixins
2 | // - Responsive image
3 | // - Retina image
4 |
5 | // Responsive image
6 | //
7 | // Keep images from scaling beyond the width of their parents.
8 |
9 | @mixin img-fluid {
10 | // Part 1: Set a maximum relative to the parent
11 | max-width: 100%;
12 | // Part 2: Override the height to auto, otherwise images will be stretched
13 | // when setting a width and height attribute on the img element.
14 | height: auto;
15 | }
16 |
17 | // Retina image
18 | // Short retina mixin for setting background-image and -size.
19 |
20 | @mixin img-retina($file-1x, $file-2x, $width-1x, $height-1x) {
21 | background-image: url($file-1x);
22 |
23 | // There's no such thing as unprefixed min-device-pixel-ratio since it's nonstandard.
24 | // Compatibility info: http://caniuse.com/#feat=css-media-resolution
25 | @media only screen and (min-resolution: 192dpi), only screen and (min-resolution: 2dppx) {
26 | background-image: url($file-2x);
27 | background-size: $width-1x $height-1x;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_list-group.scss:
--------------------------------------------------------------------------------
1 | // List Groups
2 |
3 | @mixin list-group-item-variant($state, $background, $color) {
4 | .list-group-item-#{$state} {
5 | color: $color;
6 | background-color: $background;
7 | }
8 |
9 | a.list-group-item-#{$state},
10 | button.list-group-item-#{$state} {
11 | color: $color;
12 |
13 | .list-group-item-heading {
14 | color: inherit;
15 | }
16 |
17 | @include hover-focus {
18 | color: $color;
19 | background-color: darken($background, 5%);
20 | }
21 |
22 | &.active {
23 | color: #fff;
24 | background-color: $color;
25 | border-color: $color;
26 | }
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_lists.scss:
--------------------------------------------------------------------------------
1 | // Lists
2 |
3 | // Unstyled keeps list items block level, just removes default browser padding and list-style
4 | @mixin list-unstyled {
5 | padding-left: 0;
6 | list-style: none;
7 | }
8 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_nav-divider.scss:
--------------------------------------------------------------------------------
1 | // Horizontal dividers
2 | //
3 | // Dividers (basically an hr) within dropdowns and nav lists
4 |
5 | @mixin nav-divider($color: #e5e5e5) {
6 | height: 1px;
7 | margin: ($spacer-y / 2) 0;
8 | overflow: hidden;
9 | background-color: $color;
10 | }
11 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_navbar-align.scss:
--------------------------------------------------------------------------------
1 | // Navbar vertical align
2 | //
3 | // Vertically center elements in the navbar.
4 | // Example: an element has a height of 30px, so write out `.navbar-vertical-align(30px);` to calculate the appropriate top margin.
5 |
6 | // @mixin navbar-vertical-align($element-height) {
7 | // margin-top: (($navbar-height - $element-height) / 2);
8 | // margin-bottom: (($navbar-height - $element-height) / 2);
9 | // }
10 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_pagination.scss:
--------------------------------------------------------------------------------
1 | // Pagination
2 |
3 | @mixin pagination-size($padding-y, $padding-x, $font-size, $line-height, $border-radius) {
4 | .page-link {
5 | padding: $padding-y $padding-x;
6 | font-size: $font-size;
7 | }
8 |
9 | .page-item {
10 | &:first-child {
11 | .page-link {
12 | @include border-left-radius($border-radius);
13 | }
14 | }
15 | &:last-child {
16 | .page-link {
17 | @include border-right-radius($border-radius);
18 | }
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_reset-text.scss:
--------------------------------------------------------------------------------
1 | @mixin reset-text {
2 | font-family: $font-family-base;
3 | // We deliberately do NOT reset font-size or word-wrap.
4 | font-style: normal;
5 | font-weight: $font-weight-normal;
6 | letter-spacing: normal;
7 | line-break: auto;
8 | line-height: $line-height-base;
9 | text-align: left; // Fallback for where `start` is not supported
10 | text-align: start;
11 | text-decoration: none;
12 | text-shadow: none;
13 | text-transform: none;
14 | white-space: normal;
15 | word-break: normal;
16 | word-spacing: normal;
17 | }
18 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_resize.scss:
--------------------------------------------------------------------------------
1 | // Resize anything
2 |
3 | @mixin resizable($direction) {
4 | resize: $direction; // Options: horizontal, vertical, both
5 | overflow: auto; // Per CSS3 UI, `resize` only applies when `overflow` isn't `visible`
6 | }
7 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Only display content to screen readers
2 | //
3 | // See: http://a11yproject.com/posts/how-to-hide-content
4 |
5 | @mixin sr-only {
6 | position: absolute;
7 | width: 1px;
8 | height: 1px;
9 | padding: 0;
10 | margin: -1px;
11 | overflow: hidden;
12 | clip: rect(0, 0, 0, 0);
13 | border: 0;
14 | }
15 |
16 | // Use in conjunction with .sr-only to only display content when it's focused.
17 | //
18 | // Useful for "Skip to main content" links; see https://www.w3.org/TR/2013/NOTE-WCAG20-TECHS-20130905/G1
19 | //
20 | // Credit: HTML5 Boilerplate
21 |
22 | @mixin sr-only-focusable {
23 | &:active,
24 | &:focus {
25 | position: static;
26 | width: auto;
27 | height: auto;
28 | margin: 0;
29 | overflow: visible;
30 | clip: auto;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_size.scss:
--------------------------------------------------------------------------------
1 | // Sizing shortcuts
2 |
3 | @mixin size($width, $height: $width) {
4 | width: $width;
5 | height: $height;
6 | }
7 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_table-row.scss:
--------------------------------------------------------------------------------
1 | // Tables
2 |
3 | @mixin table-row-variant($state, $background) {
4 | // Exact selectors below required to override `.table-striped` and prevent
5 | // inheritance to nested tables.
6 | .table-#{$state} {
7 | &,
8 | > th,
9 | > td {
10 | background-color: $background;
11 | }
12 | }
13 |
14 | // Hover states for `.table-hover`
15 | // Note: this is not available for cells or rows within `thead` or `tfoot`.
16 | .table-hover {
17 | $hover-background: darken($background, 5%);
18 |
19 | .table-#{$state} {
20 | @include hover {
21 | background-color: $hover-background;
22 |
23 | > td,
24 | > th {
25 | background-color: $hover-background;
26 | }
27 | }
28 | }
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_text-emphasis.scss:
--------------------------------------------------------------------------------
1 | // Typography
2 |
3 | @mixin text-emphasis-variant($parent, $color) {
4 | #{$parent} {
5 | color: $color !important;
6 | }
7 | a#{$parent} {
8 | @include hover-focus {
9 | color: darken($color, 10%) !important;
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_text-hide.scss:
--------------------------------------------------------------------------------
1 | // CSS image replacement
2 | @mixin text-hide() {
3 | font: 0/0 a;
4 | color: transparent;
5 | text-shadow: none;
6 | background-color: transparent;
7 | border: 0;
8 | }
9 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_text-truncate.scss:
--------------------------------------------------------------------------------
1 | // Text truncate
2 | // Requires inline-block or block for proper styling
3 |
4 | @mixin text-truncate() {
5 | overflow: hidden;
6 | text-overflow: ellipsis;
7 | white-space: nowrap;
8 | }
9 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_transforms.scss:
--------------------------------------------------------------------------------
1 | // Applies the given styles only when the browser support CSS3 3D transforms.
2 | @mixin if-supports-3d-transforms() {
3 | @media (-webkit-transform-3d) {
4 | // Old Safari, Old Android
5 | // http://caniuse.com/#feat=css-featurequeries
6 | // https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-webkit-transform-3d
7 | @content;
8 | }
9 |
10 | @supports (transform: translate3d(0, 0, 0)) {
11 | // The Proper Way: Using a CSS feature query
12 | @content;
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/mixins/_visibility.scss:
--------------------------------------------------------------------------------
1 | // Visibility
2 |
3 | @mixin invisible {
4 | visibility: hidden !important;
5 | }
6 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_align.scss:
--------------------------------------------------------------------------------
1 | .align-baseline {
2 | vertical-align: baseline !important;
3 | } // Browser default
4 | .align-top {
5 | vertical-align: top !important;
6 | }
7 | .align-middle {
8 | vertical-align: middle !important;
9 | }
10 | .align-bottom {
11 | vertical-align: bottom !important;
12 | }
13 | .align-text-bottom {
14 | vertical-align: text-bottom !important;
15 | }
16 | .align-text-top {
17 | vertical-align: text-top !important;
18 | }
19 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_background.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Contextual backgrounds
3 | //
4 |
5 | .bg-faded {
6 | background-color: darken($body-bg, 3%);
7 | }
8 |
9 | @include bg-variant('.bg-primary', $brand-primary);
10 |
11 | @include bg-variant('.bg-success', $brand-success);
12 |
13 | @include bg-variant('.bg-info', $brand-info);
14 |
15 | @include bg-variant('.bg-warning', $brand-warning);
16 |
17 | @include bg-variant('.bg-danger', $brand-danger);
18 |
19 | @include bg-variant('.bg-inverse', $brand-inverse);
20 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_borders.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Border
3 | //
4 |
5 | .border-0 {
6 | border: 0 !important;
7 | }
8 | .border-top-0 {
9 | border-top: 0 !important;
10 | }
11 | .border-right-0 {
12 | border-right: 0 !important;
13 | }
14 | .border-bottom-0 {
15 | border-bottom: 0 !important;
16 | }
17 | .border-left-0 {
18 | border-left: 0 !important;
19 | }
20 |
21 | //
22 | // Border-radius
23 | //
24 |
25 | .rounded {
26 | @include border-radius($border-radius);
27 | }
28 | .rounded-top {
29 | @include border-top-radius($border-radius);
30 | }
31 | .rounded-right {
32 | @include border-right-radius($border-radius);
33 | }
34 | .rounded-bottom {
35 | @include border-bottom-radius($border-radius);
36 | }
37 | .rounded-left {
38 | @include border-left-radius($border-radius);
39 | }
40 |
41 | .rounded-circle {
42 | border-radius: 50%;
43 | }
44 |
45 | .rounded-0 {
46 | border-radius: 0;
47 | }
48 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_clearfix.scss:
--------------------------------------------------------------------------------
1 | .clearfix {
2 | @include clearfix();
3 | }
4 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_display.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Display utilities
3 | //
4 |
5 | @each $breakpoint in map-keys($grid-breakpoints) {
6 | @include media-breakpoint-up($breakpoint) {
7 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
8 |
9 | .d#{$infix}-none {
10 | display: none !important;
11 | }
12 | .d#{$infix}-inline {
13 | display: inline !important;
14 | }
15 | .d#{$infix}-inline-block {
16 | display: inline-block !important;
17 | }
18 | .d#{$infix}-block {
19 | display: block !important;
20 | }
21 | .d#{$infix}-table {
22 | display: table !important;
23 | }
24 | .d#{$infix}-table-cell {
25 | display: table-cell !important;
26 | }
27 | .d#{$infix}-flex {
28 | display: flex !important;
29 | }
30 | .d#{$infix}-inline-flex {
31 | display: inline-flex !important;
32 | }
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_float.scss:
--------------------------------------------------------------------------------
1 | @each $breakpoint in map-keys($grid-breakpoints) {
2 | @include media-breakpoint-up($breakpoint) {
3 | $infix: breakpoint-infix($breakpoint, $grid-breakpoints);
4 |
5 | .float#{$infix}-left {
6 | @include float-left;
7 | }
8 | .float#{$infix}-right {
9 | @include float-right;
10 | }
11 | .float#{$infix}-none {
12 | @include float-none;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_position.scss:
--------------------------------------------------------------------------------
1 | // Positioning
2 |
3 | .fixed-top {
4 | position: fixed;
5 | top: 0;
6 | right: 0;
7 | left: 0;
8 | z-index: $zindex-fixed;
9 | }
10 |
11 | .fixed-bottom {
12 | position: fixed;
13 | right: 0;
14 | bottom: 0;
15 | left: 0;
16 | z-index: $zindex-fixed;
17 | }
18 |
19 | .sticky-top {
20 | position: sticky;
21 | top: 0;
22 | z-index: $zindex-sticky;
23 | }
24 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_screenreaders.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Screenreaders
3 | //
4 |
5 | .sr-only {
6 | @include sr-only();
7 | }
8 |
9 | .sr-only-focusable {
10 | @include sr-only-focusable();
11 | }
12 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_sizing.scss:
--------------------------------------------------------------------------------
1 | // Width and height
2 |
3 | @each $prop, $abbrev in (width: w, height: h) {
4 | @each $size, $length in $sizes {
5 | .#{$abbrev}-#{$size} {
6 | #{$prop}: $length !important;
7 | }
8 | }
9 | }
10 |
11 | .mw-100 {
12 | max-width: 100% !important;
13 | }
14 | .mh-100 {
15 | max-height: 100% !important;
16 | }
17 |
--------------------------------------------------------------------------------
/src/styles/vendors/bootstrap/utilities/_visibility.scss:
--------------------------------------------------------------------------------
1 | //
2 | // Visibility utilities
3 | //
4 |
5 | .invisible {
6 | @include invisible();
7 | }
8 |
9 | // Responsive visibility utilities
10 |
11 | @each $bp in map-keys($grid-breakpoints) {
12 | .hidden-#{$bp}-up {
13 | @include media-breakpoint-up($bp) {
14 | display: none !important;
15 | }
16 | }
17 | .hidden-#{$bp}-down {
18 | @include media-breakpoint-down($bp) {
19 | display: none !important;
20 | }
21 | }
22 | }
23 |
24 | // Print utilities
25 | //
26 | // Media queries are placed on the inside to be mixin-friendly.
27 |
28 | .visible-print-block {
29 | display: none !important;
30 |
31 | @media print {
32 | display: block !important;
33 | }
34 | }
35 | .visible-print-inline {
36 | display: none !important;
37 |
38 | @media print {
39 | display: inline !important;
40 | }
41 | }
42 | .visible-print-inline-block {
43 | display: none !important;
44 |
45 | @media print {
46 | display: inline-block !important;
47 | }
48 | }
49 |
50 | .hidden-print {
51 | @media print {
52 | display: none !important;
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/src/styles/vendors/ceaser/_ceaser-easing.sass:
--------------------------------------------------------------------------------
1 | @import "ceaser-easing/ceaser"
--------------------------------------------------------------------------------
/src/styles/vendors/ceaser/ceaser-easing/_ceaser.sass:
--------------------------------------------------------------------------------
1 | // @import "compass/css3/transition"
2 | @import "ease-types"
3 | @import "easing-vars"
4 |
5 | $ceaser-legacy: false !default
6 |
7 | @function ceaser($type: $ease)
8 | @if $ceaser-legacy
9 | $easingValue: returnEaseType($type)
10 | @return cubic-bezier(unquote($easingValue))
11 | @else
12 | @return cubic-bezier(unquote($type))
13 |
14 | @mixin ceaser-transition($properties: all, $duration: 500ms, $type: $ease, $delay: 0ms)
15 | @if $ceaser-legacy
16 | $easingValue : returnEaseType($type)
17 | @include transition($properties $duration cubic-bezier(unquote($easingValue)) $delay)
18 | @else
19 | @include transition($properties $duration cubic-bezier(unquote($type)) $delay)
20 |
--------------------------------------------------------------------------------
/src/styles/vendors/ctemplar-fonts/fonts.scss:
--------------------------------------------------------------------------------
1 | @import 'autocrypt';
2 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_animated.scss:
--------------------------------------------------------------------------------
1 | // Animated Icons
2 | // --------------------------
3 |
4 | .#{$fa-css-prefix}-spin {
5 | animation: fa-spin 2s infinite linear;
6 | }
7 |
8 | .#{$fa-css-prefix}-pulse {
9 | animation: fa-spin 1s infinite steps(8);
10 | }
11 |
12 | @keyframes fa-spin {
13 | 0% {
14 | transform: rotate(0deg);
15 | }
16 |
17 | 100% {
18 | transform: rotate(360deg);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_bordered-pulled.scss:
--------------------------------------------------------------------------------
1 | // Bordered & Pulled
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-border {
5 | border: solid 0.08em $fa-border-color;
6 | border-radius: 0.1em;
7 | padding: 0.2em 0.25em 0.15em;
8 | }
9 |
10 | .#{$fa-css-prefix}-pull-left {
11 | float: left;
12 | }
13 | .#{$fa-css-prefix}-pull-right {
14 | float: right;
15 | }
16 |
17 | .#{$fa-css-prefix},
18 | .fas,
19 | .far,
20 | .fal,
21 | .fab {
22 | &.#{$fa-css-prefix}-pull-left {
23 | margin-right: 0.3em;
24 | }
25 | &.#{$fa-css-prefix}-pull-right {
26 | margin-left: 0.3em;
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_core.scss:
--------------------------------------------------------------------------------
1 | // Base Class Definition
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix},
5 | .fas,
6 | .far,
7 | .fal,
8 | .fab {
9 | -moz-osx-font-smoothing: grayscale;
10 | -webkit-font-smoothing: antialiased;
11 | display: inline-block;
12 | font-style: normal;
13 | font-variant: normal;
14 | text-rendering: auto;
15 | line-height: 1;
16 | }
17 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_fixed-width.scss:
--------------------------------------------------------------------------------
1 | // Fixed Width Icons
2 | // -------------------------
3 | .#{$fa-css-prefix}-fw {
4 | text-align: center;
5 | width: (20em / 16);
6 | }
7 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_fontawesome.scss:
--------------------------------------------------------------------------------
1 | /*!
2 | * Font Awesome Free 5.0.9 by @fontawesome - https://fontawesome.com
3 | * License - https://fontawesome.com/license (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License)
4 | */
5 | @import 'variables';
6 | @import 'mixins';
7 | @import 'core';
8 | @import 'larger';
9 | @import 'fixed-width';
10 | @import 'list';
11 | @import 'bordered-pulled';
12 | @import 'animated';
13 | @import 'rotated-flipped';
14 | @import 'stacked';
15 | @import 'icons';
16 | @import 'screen-reader';
17 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_larger.scss:
--------------------------------------------------------------------------------
1 | // Icon Sizes
2 | // -------------------------
3 |
4 | // makes the font 33% larger relative to the icon container
5 | .#{$fa-css-prefix}-lg {
6 | font-size: (4em / 3);
7 | line-height: (3em / 4);
8 | vertical-align: -0.0667em;
9 | }
10 |
11 | .#{$fa-css-prefix}-xs {
12 | font-size: 0.75em;
13 | }
14 |
15 | .#{$fa-css-prefix}-sm {
16 | font-size: 0.875em;
17 | }
18 |
19 | @for $i from 1 through 10 {
20 | .#{$fa-css-prefix}-#{$i}x {
21 | font-size: $i * 1em;
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_list.scss:
--------------------------------------------------------------------------------
1 | // List Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-ul {
5 | list-style-type: none;
6 | margin-left: $fa-li-width * 5/4;
7 | padding-left: 0;
8 |
9 | > li {
10 | position: relative;
11 | }
12 | }
13 |
14 | .#{$fa-css-prefix}-li {
15 | left: -$fa-li-width;
16 | position: absolute;
17 | text-align: center;
18 | width: $fa-li-width;
19 | line-height: inherit;
20 | }
21 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_rotated-flipped.scss:
--------------------------------------------------------------------------------
1 | // Rotated & Flipped Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-rotate-90 {
5 | @include fa-icon-rotate(90deg, 1);
6 | }
7 | .#{$fa-css-prefix}-rotate-180 {
8 | @include fa-icon-rotate(180deg, 2);
9 | }
10 | .#{$fa-css-prefix}-rotate-270 {
11 | @include fa-icon-rotate(270deg, 3);
12 | }
13 |
14 | .#{$fa-css-prefix}-flip-horizontal {
15 | @include fa-icon-flip(-1, 1, 0);
16 | }
17 | .#{$fa-css-prefix}-flip-vertical {
18 | @include fa-icon-flip(1, -1, 2);
19 | }
20 | .#{$fa-css-prefix}-flip-horizontal.#{$fa-css-prefix}-flip-vertical {
21 | @include fa-icon-flip(-1, -1, 2);
22 | }
23 |
24 | // Hook for IE8-9
25 | // -------------------------
26 |
27 | :root {
28 | .#{$fa-css-prefix}-rotate-90,
29 | .#{$fa-css-prefix}-rotate-180,
30 | .#{$fa-css-prefix}-rotate-270,
31 | .#{$fa-css-prefix}-flip-horizontal,
32 | .#{$fa-css-prefix}-flip-vertical {
33 | filter: none;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_screen-reader.scss:
--------------------------------------------------------------------------------
1 | // Screen Readers
2 | // -------------------------
3 |
4 | .sr-only {
5 | @include sr-only;
6 | }
7 | .sr-only-focusable {
8 | @include sr-only-focusable;
9 | }
10 |
--------------------------------------------------------------------------------
/src/styles/vendors/fontawesome/_stacked.scss:
--------------------------------------------------------------------------------
1 | // Stacked Icons
2 | // -------------------------
3 |
4 | .#{$fa-css-prefix}-stack {
5 | display: inline-block;
6 | height: 2em;
7 | line-height: 2em;
8 | position: relative;
9 | vertical-align: middle;
10 | width: 2em;
11 | }
12 |
13 | .#{$fa-css-prefix}-stack-1x,
14 | .#{$fa-css-prefix}-stack-2x {
15 | left: 0;
16 | position: absolute;
17 | text-align: center;
18 | width: 100%;
19 | }
20 |
21 | .#{$fa-css-prefix}-stack-1x {
22 | line-height: inherit;
23 | }
24 |
25 | .#{$fa-css-prefix}-stack-2x {
26 | font-size: 2em;
27 | }
28 |
29 | .#{$fa-css-prefix}-inverse {
30 | color: $fa-inverse;
31 | }
32 |
--------------------------------------------------------------------------------
/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing';
6 |
7 | declare const require: any;
8 |
9 | // First, initialize the Angular testing environment.
10 | getTestBed().initTestEnvironment(BrowserDynamicTestingModule, platformBrowserDynamicTesting());
11 | // Then we find all the tests.
12 | const context = require.context('./', true, /\.spec\.ts$/);
13 | // And load the modules.
14 | context.keys().map(context);
15 |
--------------------------------------------------------------------------------
/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "module": "es2015",
6 | "baseUrl": "",
7 | "types": []
8 | },
9 | "exclude": ["**/*.spec.ts"]
10 | }
11 |
--------------------------------------------------------------------------------
/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "module": "commonjs",
6 | "types": ["jasmine", "node"]
7 | },
8 | "files": ["test.ts"],
9 | "include": ["**/*.spec.ts", "**/*.d.ts"],
10 | "exclude": ["dist", "release", "node_modules"]
11 | }
12 |
--------------------------------------------------------------------------------
/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | interface NodeModule {
3 | id: string;
4 | }
5 |
6 | declare module 'cssfilter';
7 | declare module 'bcryptjs';
8 |
9 | declare module '@ckeditor/ckeditor5-build-decoupled-document' {
10 | const DecoupledEditorBuild: any;
11 |
12 | export = DecoupledEditorBuild;
13 | }
14 |
15 | declare module '@ckeditor/ckeditor5-inspector' {
16 | const CKEditorInspectorBuild: any;
17 |
18 | export = CKEditorInspectorBuild;
19 | }
20 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "module": "es2020",
5 | "outDir": "./dist/out-tsc",
6 | "sourceMap": true,
7 | "declaration": false,
8 | "moduleResolution": "node",
9 | "noImplicitAny": true,
10 | "experimentalDecorators": true,
11 | "removeComments": true,
12 | "target": "es2015",
13 | "typeRoots": ["node_modules/@types"],
14 | "lib": ["es2018", "dom"],
15 | "skipLibCheck": true,
16 | "allowJs": true
17 | },
18 | "files": ["src/main.ts", "src/polyfills.ts"],
19 | "include": ["src/**/*.d.ts"],
20 | "exclude": ["node_modules"]
21 | }
22 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | export const node = {
2 | path: true,
3 | crypto: true,
4 | fs: 'empty',
5 | };
6 |
--------------------------------------------------------------------------------